| # | Bài tập | Điểm | Thời gian: | Giới hạn bộ nhớ |
|---|---|---|---|---|
| 1 | Google Code Jam 2011 - A.I. War | 32 | 2.0s | 1G |
| 2 | Google Code Jam 2011 - Airport Walkways | 18 | 1.0s | 1G |
| 3 | Google Code Jam 2011 - Expensive Dinner | 30 | 4.0s | 1G |
| 4 | Google Code Jam 2011 - Spinning Blade | 20 | 3.0s | 1G |
A.I. War là một trò chơi chiến thuật thời gian thực được phát triển bởi Arcen Games. Bài toán này được lấy cảm hứng từ trò chơi đó, nhưng không yêu cầu bạn phải từng chơi nó.
Bạn đang đối mặt với một trí tuệ nhân tạo (A.I.) trong một cuộc chiến sinh tử vì tương lai của thiên hà. Để đánh bại A.I., bạn cần đe dọa hành tinh quê hương của nó. Một số hành tinh được kết nối với nhau bằng các lỗ sâu (wormhole); bất kỳ hành tinh nào cũng có thể được kết nối với bất kỳ số lượng hành tinh nào khác bằng các lỗ sâu này.
Bạn bắt đầu bằng việc chỉ sở hữu hành tinh quê hương của mình. Mỗi lượt, bạn có thể chinh phục bất kỳ hành tinh nào mà bạn đe dọa. Bạn đe dọa một hành tinh nếu bạn không sở hữu nó, và nó được kết nối bằng một lỗ sâu với bất kỳ hành tinh nào bạn đang sở hữu. Khi bạn đã chinh phục một hành tinh, bạn sở hữu nó. Ngay khi bạn đe dọa hành tinh quê hương của A.I., bạn không được phép chinh phục thêm bất kỳ hành tinh nào nữa.
Trong khi tham gia ngày quan trọng nhất tại trường chiến thuật, bạn đã khám phá ra hai điều về A.I.:
Bạn đã kết hợp hai sự thật đó để tạo ra một chiến lược:
Cho biết các hành tinh và các lỗ sâu, bạn sẽ chinh phục bao nhiêu hành tinh và đe dọa bao nhiêu hành tinh trên đường đến căn cứ quê hương của A.I. nếu bạn tuân theo chiến lược mô tả ở trên?
Dòng đầu tiên của dữ liệu vào cho biết số lượng bộ test, T. T bộ test nối tiếp theo. Mỗi bộ test bắt đầu bằng một dòng chứa hai số nguyên cách nhau bởi dấu cách: P, số lượng hành tinh, và W, số lượng lỗ sâu. Hành tinh quê hương của bạn là hành tinh 0, và hành tinh quê hương của A.I. là hành tinh 1.
Dòng thứ hai của mỗi bộ test sẽ chứa W cặp số nguyên cách nhau bởi dấu phẩy, các cặp cách nhau bởi dấu cách \(x_i\),\(y_i\). Mỗi cặp này cho biết có một lỗ sâu hai chiều kết nối các hành tinh \(x_i\) và \(y_i\).
Đối với mỗi bộ test, hãy xuất một dòng chứa "Case #x: c t", trong đó x là số thứ tự bộ test (bắt đầu từ 1), c là số lượng hành tinh bạn chinh phục nếu tuân theo chiến lược trên, và t là số lượng hành tinh bạn đe dọa ở thời điểm kết thúc (bao gồm cả hành tinh quê hương của A.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 | 10/32 | 31,25% |
| Test Set 2 | 22/32 | 68,75% |
Ví dụ 1
4
2 1
0,1
3 3
0,1 1,2 0,2
5 5
0,4 0,2 2,4 1,2 1,4
7 9
0,6 0,2 0,4 2,4 3,4 2,3 3,5 4,5 1,5
Case #1: 0 1
Case #2: 0 2
Case #3: 1 2
Case #4: 2 4
Google Code Jam 2011, Vòng 2, bài A.I. War.
Nguồn chính thức trên Google Coding Competitions Archive, phát hành theo giấy phép Apache-2.0.
Bạn đang ở trong một sân bay, đứng tại điểm 0. Một hành lang có chiều dài \(X\) dẫn đến cổng khởi hành, nơi máy bay của bạn sắp cất cánh. Có những băng chuyền chuyển động trong hành lang, mỗi băng chuyền di chuyển với tốc độ \(w_i\). Khi bạn đi bộ hoặc chạy trên một trong những băng chuyền đó, bạn sẽ di chuyển với tốc độ (tốc độ của bạn + \(w_i\)). Các băng chuyền không thay đổi vị trí; chúng chỉ giúp bạn di chuyển nhanh hơn. Các băng chuyền không chồng lấn lên nhau: tại bất kỳ điểm nào trên hành lang, có tối đa một băng chuyền, nhưng một băng chuyền có thể bắt đầu tại điểm mà một băng chuyền khác kết thúc.
Tốc độ đi bộ bình thường của bạn là \(S\). Tuy nhiên, bạn lo lắng rằng mình có thể không kịp chuyến bay, vì vậy bạn có thể chạy một chút - bạn có thể chạy với tốc độ \(R\) trong tổng cộng tối đa \(t\) giây. Bạn không nhất thiết phải chạy trong \(t\) giây liên tục: bạn có thể chia \(t\) giây này thành bất kỳ số lượng khoảng thời gian nào, hoặc thậm chí không sử dụng hết chúng.
Bạn mất bao lâu để đến được cổng, giả sử bạn chọn khi nào đi bộ và khi nào chạy để đến nơi sớm nhất có thể?
Dòng đầu tiên của dữ liệu vào cho biết số lượng bộ thử nghiệm, \(T\). \(T\) bộ thử nghiệm tiếp theo. Mỗi bộ thử nghiệm bắt đầu bằng một dòng chứa năm số nguyên: \(X\) (chiều dài hành lang, tính bằng mét), \(S\) (tốc độ đi bộ của bạn, tính bằng mét trên giây), \(R\) (tốc độ chạy của bạn, tính bằng mét trên giây), \(t\) (thời gian chạy tối đa, tính bằng giây) và \(N\) (số lượng băng chuyền).
Mỗi dòng trong số \(N\) dòng tiếp theo chứa ba số nguyên: \(B_i\), \(E_i\) và \(w_i\) - điểm bắt đầu và điểm kết thúc của băng chuyền (tính bằng mét từ điểm xuất phát của bạn) và tốc độ của băng chuyền (tính bằng mét trên giây).
Đối với mỗi bộ thử nghiệm, hãy xuất một dòng chứa "Case #x: y", trong đó x là số thứ tự bộ thử nghiệm (bắt đầu từ 1) và y là thời gian (tính bằng giây) bạn cần để đến điểm \(X\) nếu bạn đi bộ và chạy một cách tối ưu. Các câu trả lời có sai số tương đối hoặc tuyệt đối không quá \(10^{-6}\) sẽ được chấp nhận.
Small dataset (Test set 1):
Large dataset (Test set 2):
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/18 | 44,44% |
| Test Set 2 | 10/18 | 55,56% |
Ví dụ 1
3
10 1 4 1 2
4 6 1
6 9 2
12 1 2 4 1
6 12 1
20 1 3 20 5
0 4 5
4 8 4
8 12 3
12 16 2
16 20 1
Case #1: 4.000000
Case #2: 5.500000
Case #3: 3.538095238
Giải pháp tốt nhất trong trường hợp đầu tiên là bắt đầu chạy ngay lập tức và chạy trong một giây.
Google Code Jam 2011, Vòng 2, bài Airport Walkways.
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ất cả bạn bè của bạn sẽ đi ăn tối tại một nhà hàng tối nay. Họ đều rất giỏi toán, nhưng họ cũng rất kỳ lạ: người bạn thứ \(a\) của bạn (bắt đầu từ 1) sẽ không vui trừ khi tổng chi phí của bữa ăn là một số nguyên dương và chia hết cho \(a\).
Các bạn của bạn lần lượt vào nhà hàng từng người một. Ngay khi có ai đó bước vào nhà hàng, nếu người đó không vui thì cả nhóm sẽ gọi phục vụ ngay lập tức.
Miễn là có ít nhất một người không vui trong nhà hàng, một trong những người không vui đó sẽ mua món đồ có giá thấp nhất để làm cho anh ta hoặc cô ta vui. Điều này sẽ tiếp tục cho đến khi không còn ai trong nhà hàng không vui, và sau đó người phục vụ sẽ rời đi. May mắn thay, nhà hàng bán đồ ăn ở mọi mức giá nguyên dương. Xem phần giải thích của ví dụ đầu tiên để biết thêm chi tiết.
Các bạn của bạn có thể chọn vào nhà hàng theo bất kỳ thứ tự nào. Sau khi người phục vụ đã được gọi, nếu có nhiều hơn một người không vui trong nhà hàng, bất kỳ ai trong số những người không vui đó đều có thể chọn mua một thứ gì đó trước. Cách thức thực hiện tất cả các lựa chọn đó có thể ảnh hưởng đến số lần nhóm gọi phục vụ.
Là chủ nhà hàng, bạn thuê một số người phục vụ rất mệt mỏi. Bạn muốn tính độ chênh lệch (spread) của những người bạn của mình: sự khác biệt giữa số lần tối đa họ có thể gọi phục vụ và số lần tối thiểu họ có thể gọi phục vụ.
Dòng đầu tiên của dữ liệu vào cho biết số lượng bộ test, \(T\). \(T\) bộ test tiếp theo, mỗi bộ trên một dòng. Mỗi bộ test sẽ chứa một số nguyên \(N\), số lượng bạn bè mà bạn có.
Đối với mỗi bộ test, hãy xuất một dòng chứa "Case #x: y", trong đó x là số thứ tự của bộ test (bắt đầu từ 1) và y là độ chênh lệch cho bộ test đó.
Các giới hạn cho tập nhỏ và tập lớn được nêu ở trê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 | 13/30 | 43,33% |
| Test Set 2 | 17/30 | 56,67% |
Ví dụ 1
4
1
3
6
16
Case #1: 0
Case #2: 1
Case #3: 2
Case #4: 5
Trong Case #2, giả sử các bạn của bạn đến theo thứ tự \([1, 2, 3]\). Đầu tiên #1 đến; không vui; gọi phục vụ; và mua thứ gì đó giá 1. Bây giờ không ai không vui. Tiếp theo #2 đến; không vui; gọi phục vụ; và mua thứ gì đó giá 1 (tổng cộng là 2). Bây giờ không ai không vui. Tiếp theo #3 đến; không vui; gọi phục vụ; và mua thứ gì đó giá 1 (tổng cộng là 3). Bây giờ #2 không vui, và mua thứ gì đó giá 1 (tổng cộng là 4). Bây giờ #3 không vui, và mua thứ gì đó giá 2 (tổng cộng là 6). Cuối cùng không ai không vui, và người phục vụ đã được gọi ba lần.
Giả sử thay vào đó các bạn của bạn đến theo thứ tự \([3, 1, 2]\). Đầu tiên #3 đến; không vui; gọi phục vụ; và mua thứ gì đó giá 3. Bây giờ không ai không vui. Tiếp theo #1 đến; không ai không vui. Tiếp theo #2 đến; không vui; gọi phục vụ; và mua thứ gì đó giá 1 (tổng cộng là 4). Bây giờ #3 không vui, và mua thứ gì đó giá 2 (tổng cộng là 6). Bây giờ không ai không vui, và người phục vụ đã được gọi hai lần. Độ chênh lệch là \(3 - 2 = 1\).
Google Code Jam 2011, Vòng 2, bài Expensive Dinner.
Nguồn chính thức trên Google Coding Competitions Archive, phát hành theo giấy phép Apache-2.0.
Vì đã chán với những cái bẫy trong thiết kế căn cứ bí mật của mình, bạn quyết định chọn một thứ gì đó cổ điển nhưng luôn thú vị - lưỡi dao xoay. Bạn đã đặt hàng một tấm kim loại rất nặng, từ đó bạn sẽ cắt ra lưỡi dao; một lưới ô vuông đồng nhất kích thước \(C \times R\) sẽ được vẽ trên tấm kim loại. Bạn đã xác định được hình dạng tốt nhất cho lưỡi dao -- trước tiên bạn sẽ cắt một hình vuông lớn gồm \(K \times K\) ô lưới, với \(K \ge 3\). Sau đó, bạn sẽ cắt bỏ bốn ô góc \(1 \times 1\) của hình vuông đó để tạo thành một lưỡi dao. Sau khi xác định xong tất cả những điều này, bạn bắt đầu đợi tấm kim loại được giao đến.
Khi tấm kim loại đến nơi, bạn đã bị sốc khi phát hiện ra rằng nó có những khiếm khuyết! Bạn mong đợi mỗi ô có khối lượng \(D\), nhưng hóa ra khối lượng có thể thay đổi một chút do sự khác biệt về độ dày. Điều này thật tệ vì bạn muốn lắp một trục xoay chính xác vào tâm của lưỡi dao và xoay nó thật nhanh, vì vậy trọng tâm của lưỡi dao cũng phải nằm chính xác tại tâm của nó. Định nghĩa về trọng tâm của một vật thể phẳng có thể được tìm thấy bên dưới.
Cho lưới và khối lượng của từng ô, kích thước lớn nhất có thể của lưỡi dao mà bạn có thể tạo ra để trọng tâm nằm chính xác ở tâm của nó là bao nhiêu?
Dòng đầu tiên của dữ liệu vào cho biết số lượng bộ thử nghiệm, \(T\). \(T\) bộ thử nghiệm tiếp theo. Mỗi bộ bắt đầu bằng một dòng chứa 3 số nguyên: \(R, C\) và \(D\) — kích thước của lưới và khối lượng bạn mong đợi mỗi ô sẽ có. \(R\) dòng tiếp theo, mỗi dòng chứa \(C\) chữ số \(w_{ij}\), cho biết sự chênh lệch giữa khối lượng thực tế và khối lượng mong đợi của các ô lưới. Mỗi ô có mật độ đồng nhất, nhưng có thể có khối lượng nguyên trong khoảng từ \(D + 0\) đến \(D + 9\), bao gồm cả hai đầu.
Đối với mỗi bộ thử nghiệm, hãy xuất một dòng chứa "Case #x: \(K\)", trong đó x là số thứ tự bộ thử nghiệm (bắt đầu từ 1) và \(K\) là kích thước lớn nhất có thể của lưỡi dao bạn có thể cắt ra. Nếu không tìm thấy lưỡi dao chấp nhận được nào có kích thước ít nhất là 3, hãy in "IMPOSSIBLE" thay thế.
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/20 | 40% |
| Test Set 2 | 12/20 | 60% |
Ví dụ 1
2
6 7 2
1111111
1122271
1211521
1329131
1242121
1122211
3 3 7
123
234
345
Case #1: 5
Case #2: IMPOSSIBLE
Trọng tâm của một vật thể 2D được định nghĩa chính thức là một điểm \(c\). Nếu bạn tính tổng của \((p - c) \times \text{mass}(p)\) cho tất cả các điểm \(p\) trong vật thể, bạn phải nhận được \(0\). Ở đây, \(p, c\) và \(0\) là các vectơ hai chiều. Định nghĩa này cũng hoạt động nếu bạn coi mỗi ô lưới là một "điểm", với toàn bộ khối lượng của nó tập trung tại tâm.
Trong thực tế, bạn có thể đặt ngón tay của mình dưới trọng tâm của một vật thể phẳng và giữ thăng bằng vật thể đó trên ngón tay. Nó sẽ không rơi.
Để minh họa bằng một ví dụ, lưỡi dao duy nhất có thể cắt ra trong ví dụ thứ hai, lưỡi dao \(3 \times 3\) được tạo ra bằng cách cắt bỏ các góc, có trọng tâm tại điểm \((1.54, 1.46)\), trong đó chúng ta giả định góc dưới bên trái của tấm kim loại có tọa độ \((0, 0)\), và tọa độ tăng dần sang phải và lên trên tương ứng. Điều này được xác nhận bằng cách kiểm tra đẳng thức sau: \((-1.04, 0.04) \times 9 + (-0.04, 1.04) \times 9 + (-0.04, 0.04) \times 10 + (-0.04, -0.96) \times 11 + (0.96, 0.04) \times 11 = (0, 0)\).
Google Code Jam 2011, Vòng 2, bài Spinning Blade.
Nguồn chính thức trên Google Coding Competitions Archive, phát hành theo giấy phép Apache-2.0.