| # | 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 |
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 D và stra, 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\) và \((-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\) và \((-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ò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.
Với mỗi test, in Case #x: y, trong đó \(x\) bắt đầu từ 1 và \(y\) là 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.
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ụ 1
5
2 1
ik
3 1
ijk
3 1
kji
2 6
ji
1 10000
i
Case #1: NO
Case #2: YES
Case #3: NO
Case #4: YES
Case #5: NO
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\).
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.
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\) có \(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ò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 đó.
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.
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ụ 1
3
1
3
4
1 2 1 2
1
4
Case #1: 3
Case #2: 2
Case #3: 3
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.
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.
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:
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ò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\).
Với mỗi test, in Case #x: y, trong đó \(x\) bắt đầu từ 1 và \(y\) là 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.
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ụ 1
4
2 2 2
2 1 3
4 4 1
3 2 3
Case #1: GABRIEL
Case #2: RICHARD
Case #3: RICHARD
Case #4: GABRIEL
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\).
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.
Đê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ò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.
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.
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ụ 1
4
4 11111
1 09
5 110011
0 1
Case #1: 0
Case #2: 1
Case #3: 2
Case #4: 0
Ở 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.
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.