Google Code Jam 2015 - Qualification Round

Bộ đề bài

# Bài tập Điểm Thời gian: Giới hạn bộ nhớ
1 Google Code Jam 2015 - Dijkstra 28 1.0s 1G
2 Google Code Jam 2015 - Infinite House of Pancakes 21 1.0s 1G
3 Google Code Jam 2015 - Ominous Omino 34 1.0s 1G
4 Google Code Jam 2015 - Standing Ovation 17 1.0s 1G

1. Google Code Jam 2015 - Dijkstra

Điểm: 28 Thời gian: 1.0s Bộ nhớ: 1G Input: bàn phím Output: màn hình

Nhà khoa học máy tính người Hà Lan Edsger Dijkstra có nhiều đóng góp quan trọng, trong đó có thuật toán tìm đường đi ngắn mang tên ông. Bài này không nói về thuật toán đó.

Bạn bị trừ một điểm trong bài thi thuật toán vì viết sai “Dijkstra”: giữa Dstra, bạn viết một số ký tự, mỗi ký tự là i, j hoặc k. Bạn định tranh luận để lấy lại điểm bằng quaternion, một hệ số có thật (mở rộng từ số phức) với cấu trúc phép nhân sau:

Muốn nhân hai quaternion, tra hàng của số thứ nhất và cột của số thứ hai. Ví dụ \(i\times j=k\), còn \(j\times i=-k\).

Như các ví dụ cho thấy, phép nhân quaternion không giao hoán: tồn tại \(a,b\) sao cho \(a\times b\ne b\times a\). Tuy nhiên nó có tính kết hợp: với mọi \(a,b,c\), \(a\times(b\times c)=(a\times b)\times c\).

Dấu âm tuân theo quy tắc thông thường: \((-a)\times(-b)=a\times b\)\((-a)\times b=a\times(-b)=-(a\times b)\).

Bạn muốn chứng minh phần viết sai tương đương với ijk bằng cách cắt chuỗi tại hai vị trí thành ba chuỗi con không rỗng, sao cho chuỗi trái rút gọn bằng phép nhân quaternion thành \(i\), chuỗi giữa thành \(j\), chuỗi phải thành \(k\). Ví dụ, jij được hiểu là \(j\times i\times j\); \(j\times i=-k\)\((-k)\times j=i\), nên jij rút gọn thành \(i\). Nếu làm được, bạn sẽ lấy lại điểm. Hãy xác định có thể cắt như vậy hay không.

Dữ liệu vào

Dòng đầu chứa số bộ test \(T\).

Mỗi test gồm một dòng chứa hai số nguyên \(L,X\), rồi một dòng chứa \(L\) ký tự, tất cả đều là i, j hoặc k. Chuỗi không chứa dấu âm, 1 hay ký tự nào khác. Chuỗi cần xét là chuỗi \(L\) ký tự đã cho lặp lại \(X\) lần. Chẳng hạn, với \(L=4\), \(X=3\) và chuỗi kiij, chuỗi đầy đủ là kiijkiijkiij.

Dữ liệu ra

Với mỗi test, in Case #x: y, trong đó \(x\) bắt đầu từ 1 và \(y\)YES hoặc NO tùy chuỗi có thể chia thành ba phần cho tích lần lượt \(i,j,k\) hay không.

Ràng buộc

  • \(1\le T\le100\).
  • \(1\le L\le10000\).

Phân nhóm

  • Nhỏ: \(1\le X\le10000\), \(1\le L X\le10000\).
  • Lớn: \(1\le X\le10^{12}\), \(1\le L X\le10^{16}\).

Điểm các phân nhóm

Mỗi Test Set tương ứng với một subtask trên LQDOJ. Bảng dưới đây giữ nguyên điểm chính thức của Google Code Jam và quy đổi tỷ lệ trên tổng điểm của bài.

Phân nhóm Điểm Google Code Jam Tỷ lệ điểm của bài
Test Set 1 11/28 39,29%
Test Set 2 17/28 60,71%

Ví dụ

Ví dụ 1

Input
5
2 1
ik
3 1
ijk
3 1
kji
2 6
ji
1 10000
i
Output
Case #1: NO
Case #2: YES
Case #3: NO
Case #4: YES
Case #5: NO
Note

Test 1 quá ngắn để chia thành ba chuỗi con.

Test 2 chỉ cần chia thành i, j, k.

Test 3 chỉ có thể chia thành k, j, i, không thỏa yêu cầu.

Test 4 có chuỗi jijijijijiji; có thể chia thành jij (rút gọn thành \(i\)), iji (thành \(j\)), và jijiji (thành \(k\)).

Ở test 5, dù chọn các đoạn thế nào, không đoạn nào có thể rút gọn thành \(j\) hoặc \(k\).

Nguồn

Google Code Jam 2015, Vòng loại, bài Dijkstra.

Nguồn chính thức trên Google Coding Competitions Archive, phát hành theo giấy phép Apache-2.0.

2. Google Code Jam 2015 - Infinite House of Pancakes

Điểm: 21 Thời gian: 1.0s Bộ nhớ: 1G Input: bàn phím Output: màn hình

Tại Nhà Bánh kếp Vô hạn, chỉ có hữu hạn chiếc bánh nhưng có vô hạn thực khách sẵn lòng ăn chúng! Khi nhà hàng mở cửa phục vụ bữa sáng, trong vô hạn thực khách có đúng \(D\) người mang đĩa không rỗng; đĩa thứ \(i\)\(P_i\) chiếc bánh. Mọi người còn lại có đĩa rỗng.

Thông thường, mỗi phút, mọi thực khách có đĩa không rỗng đều ăn một chiếc bánh trên đĩa mình. Tuy nhiên, một số phút có thể là phút đặc biệt. Trong một phút đặc biệt, quản lý yêu cầu mọi người chú ý, chọn một thực khách có đĩa không rỗng, nhấc một số dương chiếc bánh khỏi đĩa đó và chuyển chúng sang đúng một đĩa khác (đang rỗng hoặc không rỗng). Không ai ăn trong phút đặc biệt, vì làm vậy là bất lịch sự.

Bạn là quản lý trực sáng nay và phải quyết định phút nào, nếu có, là phút đặc biệt, cũng như chuyển bánh nào đi đâu. Nói cách khác, ở mỗi phút bạn hoặc không làm gì để mọi người ăn, hoặc tuyên bố phút đặc biệt và thực hiện đúng một lần chuyển như trên.

Bữa sáng kết thúc khi không còn chiếc bánh nào. Bạn có thể khiến điều đó xảy ra nhanh đến mức nào?

Dữ liệu vào

Dòng đầu chứa số bộ test \(T\). Mỗi test gồm một dòng chứa \(D\), số thực khách ban đầu có đĩa không rỗng, rồi một dòng chứa \(D\) số nguyên cách nhau bởi dấu cách, là số bánh trên các đĩa đó.

Dữ liệu ra

Với mỗi test, in Case #x: y, trong đó \(x\) bắt đầu từ 1 và \(y\) là số phút nhỏ nhất để kết thúc bữa sáng.

Ràng buộc

  • \(1\le T\le100\).

Phân nhóm

  • Nhỏ: \(1\le D\le6\), \(1\le P_i\le9\).
  • Lớn: \(1\le D\le1000\), \(1\le P_i\le1000\).

Điểm các phân nhóm

Mỗi Test Set tương ứng với một subtask trên LQDOJ. Bảng dưới đây giữ nguyên điểm chính thức của Google Code Jam và quy đổi tỷ lệ trên tổng điểm của bài.

Phân nhóm Điểm Google Code Jam Tỷ lệ điểm của bài
Test Set 1 9/21 42,86%
Test Set 2 12/21 57,14%

Ví dụ

Ví dụ 1

Input
3
1
3
4
1 2 1 2
1
4
Output
Case #1: 3
Case #2: 2
Case #3: 3
Note

Test 1 có một thực khách với 3 chiếc bánh. Một chiến lược tối ưu là: phút 1 để người đó ăn một chiếc; phút 2 là phút đặc biệt, chuyển một chiếc sang đĩa rỗng của người khác (luôn có vô hạn đĩa rỗng), và phút này không ai ăn; phút 3, hai người cùng ăn hai chiếc cuối.

Ở test 2, tối ưu là để mọi người ăn trong 2 phút, không gián đoạn, và họ ăn hết bánh.

Ở test 3, một người có 4 chiếc. Tối ưu là dùng phút đầu làm phút đặc biệt, chuyển hai chiếc sang một đĩa rỗng, rồi để hai người ăn trong phút thứ hai và thứ ba.

Nguồn

Google Code Jam 2015, Vòng loại, bài Infinite House of Pancakes.

Nguồn chính thức trên Google Coding Competitions Archive, phát hành theo giấy phép Apache-2.0.

3. Google Code Jam 2015 - Ominous Omino

Điểm: 34 Thời gian: 1.0s Bộ nhớ: 1G Input: bàn phím Output: màn hình

Một \(N\)-omino là một hình hai chiều tạo bởi \(N\) ô vuông đơn vị ghép trọn cạnh với nhau. Chính xác hơn, 1-omino là một ô vuông \(1\times1\), còn một \(N\)-omino là một \((N-1)\)-omino được ghép một hay nhiều cạnh với một ô vuông \(1\times1\) kề nó. Trong bài này, hai \(N\)-omino được xem là giống nhau nếu có thể biến hình này thành hình kia bằng phép phản chiếu và/hoặc phép quay. Chẳng hạn, đây là năm 4-omino có thể có:

Và đây là một số trong 108 hình 7-omino có thể có:

Richard và Gabriel chơi một trò chơi với ba giá trị định trước \(X,R,C\) theo luật sau:

  1. Richard chọn một hình bất kỳ trong các \(X\)-omino có thể có.
  2. Gabriel phải dùng ít nhất một bản sao của \(X\)-omino đó, cùng với số lượng tùy ý bản sao của bất kỳ \(X\)-omino nào khác (có thể gồm chính hình Richard chọn), để phủ kín một lưới \(R\times C\), không chồng lấn và không tràn ra ngoài. Mỗi ô lưới phải được phủ bởi đúng một trong \(X\) ô của một \(X\)-omino. Gabriel được quay hoặc phản chiếu bao nhiêu hình tùy ý, kể cả hình Richard chọn. Nếu phủ kín được lưới thì Gabriel thắng; nếu không, Richard thắng.

Với \(X,R,C\) cho trước, Richard có thể chọn một \(X\)-omino bảo đảm mình thắng, hay Gabriel được bảo đảm thắng bất kể Richard chọn gì?

Dữ liệu vào

Dòng đầu chứa số bộ test \(T\). Mỗi test là một dòng gồm ba số nguyên cách nhau bởi dấu cách: \(X,R,C\).

Dữ liệu ra

Với mỗi test, in Case #x: y, trong đó \(x\) bắt đầu từ 1 và \(y\)RICHARD nếu tồn tại lựa chọn bảo đảm Richard thắng, hoặc GABRIEL nếu Gabriel thắng với mọi lựa chọn.

Ràng buộc

Phân nhóm

  • Nhỏ: \(T=64\), \(1\le X,R,C\le4\).
  • Lớn: \(1\le T\le100\), \(1\le X,R,C\le20\).

Điểm các phân nhóm

Mỗi Test Set tương ứng với một subtask trên LQDOJ. Bảng dưới đây giữ nguyên điểm chính thức của Google Code Jam và quy đổi tỷ lệ trên tổng điểm của bài.

Phân nhóm Điểm Google Code Jam Tỷ lệ điểm của bài
Test Set 1 8/34 23,53%
Test Set 2 26/34 76,47%

Ví dụ

Ví dụ 1

Input
4
2 2 2
2 1 3
4 4 1
3 2 3
Output
Case #1: GABRIEL
Case #2: RICHARD
Case #3: RICHARD
Case #4: GABRIEL
Note

Test 1: Richard chỉ có thể chọn domino \(1\times2\). Dù Gabriel đặt nó thế nào trên lưới \(2\times2\), phần trống còn lại vừa khít một domino nữa, nên Gabriel thắng.

Test 2: Richard vẫn phải chọn domino, nhưng nó luôn để lại một lỗ \(1\times1\) trên lưới \(1\times3\), không thể lấp bằng 2-omino, nên Richard thắng.

Test 3: Richard có thể chọn 4-omino hình vuông \(2\times2\); nó không thể nằm trọn trong lưới \(4\times1\), nên Richard thắng.

Test 4: Richard có thể chọn thanh thẳng hoặc hình chữ L gồm 3 ô. Trong cả hai trường hợp, Gabriel đặt được hình đó và dùng một bản cùng loại để lấp phần còn lại của lưới \(2\times3\).

Nguồn

Google Code Jam 2015, Vòng loại, bài Ominous Omino.

Nguồn chính thức trên Google Coding Competitions Archive, phát hành theo giấy phép Apache-2.0.

4. Google Code Jam 2015 - Standing Ovation

Điểm: 17 Thời gian: 1.0s Bộ nhớ: 1G Input: bàn phím Output: màn hình

Đêm khai mạc opera đã đến, và bạn của bạn là prima donna (nữ ca sĩ chính). Bạn không có mặt trong khán phòng, nhưng muốn chắc chắn rằng cô ấy nhận được một màn đứng dậy vỗ tay: mọi khán giả đều đứng lên và vỗ tay cho cô.

Ban đầu, toàn bộ khán giả đều ngồi. Mỗi người có một mức độ e ngại. Người có mức \(S_i\) sẽ chờ cho đến khi ít nhất \(S_i\) khán giả khác đã đứng dậy vỗ tay; ngay khi điều đó xảy ra, người ấy cũng lập tức đứng lên vỗ tay. Nếu \(S_i=0\), người ấy luôn đứng dậy ngay, bất kể những người khác làm gì. Chẳng hạn, người có \(S_i=2\) vẫn ngồi lúc đầu, nhưng sẽ đứng lên sau khi thấy ít nhất hai người khác đang đứng và vỗ tay.

Bạn biết mức độ e ngại của tất cả khán giả và sẵn sàng mời thêm bạn của prima donna để cuối cùng cả khán phòng đều đứng lên. Mỗi người bạn được mời có thể mang bất kỳ mức độ e ngại nào bạn muốn, không nhất thiết giống nhau. Hỏi cần mời ít nhất bao nhiêu người để bảo đảm có một màn đứng dậy vỗ tay?

Dữ liệu vào

Dòng đầu chứa số bộ test \(T\).

Mỗi test gồm một dòng chứa \(S_{max}\), mức lớn nhất của người e ngại nhất trong khán phòng, tiếp theo là một chuỗi gồm \(S_{max}+1\) chữ số. Chữ số thứ \(k\) của chuỗi (đếm từ 0) là số khán giả có mức e ngại \(k\). Ví dụ, 409 nghĩa là có bốn người với \(S_i=0\), chín người với \(S_i=2\), và không có ai với \(S_i=1\) hay mức nào khác. Ban đầu luôn có từ 0 đến 9 người ở mỗi mức.

Chuỗi không bao giờ kết thúc bằng 0; do đó khán phòng luôn có ít nhất một người.

Dữ liệu ra

Với mỗi test, in một dòng Case #x: y, trong đó \(x\) là số thứ tự test (bắt đầu từ 1) và \(y\) là số bạn ít nhất phải mời.

Ràng buộc

  • \(1\le T\le100\).

Phân nhóm

  • Nhỏ: \(0\le S_{max}\le6\).
  • Lớn: \(0\le S_{max}\le1000\).

Điểm các phân nhóm

Mỗi Test Set tương ứng với một subtask trên LQDOJ. Bảng dưới đây giữ nguyên điểm chính thức của Google Code Jam và quy đổi tỷ lệ trên tổng điểm của bài.

Phân nhóm Điểm Google Code Jam Tỷ lệ điểm của bài
Test Set 1 7/17 41,18%
Test Set 2 10/17 58,82%

Ví dụ

Ví dụ 1

Input
4
4 11111
1 09
5 110011
0 1
Output
Case #1: 0
Case #2: 1
Case #3: 2
Case #4: 0
Note

Ở test 1, khán giả tự tạo được màn đứng dậy vỗ tay: người có \(S_i=0\) đứng trước, rồi người có \(S_i=1\), và cứ thế tiếp tục.

Ở test 2, phải mời một người bạn có \(S_i=0\), và chỉ một người đó là đủ để cả khán phòng đứng lên.

Ở test 3, một phương án tối ưu là thêm hai khán giả có \(S_i=2\).

Ở test 4, chỉ có một khán giả và người ấy đứng lên ngay lập tức; không cần mời ai.

Nguồn

Google Code Jam 2015, Vòng loại, bài Standing Ovation.

Nguồn chính thức trên Google Coding Competitions Archive, phát hành theo giấy phép Apache-2.0.