| # | Bài tập | Điểm | Thời gian: | Giới hạn bộ nhớ |
|---|---|---|---|---|
| 1 | APIO 2024 - September | 100 (p) | 1.0s | 1G |
| 2 | APIO 2024 - Train | 100 (p) | 1.0s | 1G |
| 3 | APIO 2024 - Magic Show | 100 (p) | 1.0s | 1G |
Quảng trường trung tâm Hàng Châu là nơi có một cây cổ thụ nổi tiếng. Có thể xem cây này là một cây có gốc gồm \(N\) nút, được đánh số từ \(0\) đến \(N-1\), trong đó nút \(0\) là nút gốc.
Một nút không có nút con được gọi là nút lá. Mỗi lần rụng lá, cây chọn một nút đang là nút lá để xóa; trong cùng một ngày, cây có thể rụng lá nhiều lần.
Có \(M\) tình nguyện viên, được đánh số từ \(0\) đến \(M-1\), chịu trách nhiệm bảo vệ cây. Mỗi người độc lập ghi lại tình hình rụng lá trong năm nay như sau:
Mỗi ngày, họ thu thập chỉ số của tất cả những lá vừa rụng trong ngày đó (tức là chỉ số của các nút bị xóa trong ngày), rồi ghi các chỉ số này theo một thứ tự bất kỳ vào sau tất cả các chỉ số đã ghi trong những ngày trước.
Ví dụ, nếu trong ngày đầu tiên các lá \(3\) và \(4\) rụng, tình nguyện viên ghi 3, 4 hoặc 4, 3. Nếu trong ngày thứ hai các lá \(1\) và \(2\) rụng, người đó tiếp tục ghi 1, 2 hoặc 2, 1. Bản ghi cuối cùng có thể là một trong các dãy \((3,4,1,2)\), \((4,3,1,2)\), \((3,4,2,1)\) hoặc \((4,3,2,1)\).
Quá trình kéo dài trong \(K\) ngày, mỗi ngày đều có ít nhất một lá mới rụng, cho đến khi chỉ còn lại nút gốc.
Trong một chuyến du lịch, bạn tình cờ ghé thăm Hàng Châu vào mùa đông lạnh giá. Nhìn những cành cây trơ trụi, bạn hình dung khung cảnh lá rơi tuyệt đẹp và muốn biết trong năm nay mình có thể đã ngắm lá rơi nhiều nhất bao nhiêu ngày. Tuy nhiên, bạn chỉ tìm được bản ghi của \(M\) tình nguyện viên.
Hãy suy ra giá trị lớn nhất có thể của \(K\) phù hợp với tất cả các bản ghi.
Bạn cần cài đặt hàm sau:
int solve(int N, int M, std::vector<int> F,
std::vector<std::vector<int>> S);
Hàm phải trả về một số nguyên biểu diễn giá trị lớn nhất có thể của \(K\), tức số ngày rụng lá lớn nhất có thể theo các quy tắc trên.
Trong mỗi trường hợp kiểm thử, trình chấm có thể gọi hàm này nhiều lần. Mỗi lời gọi phải được xử lý như một kịch bản mới, hoàn toàn độc lập.
Lưu ý
Vì hàm có thể được gọi nhiều lần, hãy đặc biệt chú ý không để dữ liệu còn lại từ lời gọi trước, nhất là trạng thái trong các biến toàn cục, ảnh hưởng đến lời gọi hiện tại.
Ví dụ 1
Xét lời gọi:
solve(3, 1, {-1, 0, 0}, {{1, 2}})
Cây tương ứng được minh họa dưới đây:
Hai lá \(1\) và \(2\) có thể rụng trong cùng một ngày. Một khả năng khác là lá \(1\) rụng trong ngày đầu tiên và lá \(2\) rụng trong ngày thứ hai. Quá trình không thể kéo dài quá \(2\) ngày.
Hàm trả về 2.
Ví dụ 2
Xét lời gọi:
solve(5, 2, {-1, 0, 0, 1, 1},
{{1, 2, 3, 4}, {4, 1, 2, 3}})
Cây tương ứng được minh họa dưới đây:
Giả sử quá trình có ít nhất \(2\) ngày rụng lá. Theo các bản ghi của tình nguyện viên, lá \(4\) khi đó phải rụng vào hai ngày khác nhau, ngày đầu tiên và ngày cuối cùng, điều này là vô lý.
Hàm trả về 1.
Trình chấm mẫu đọc dữ liệu theo định dạng sau:
Với mỗi trường hợp kiểm thử, trình chấm mẫu in trên một dòng giá trị do hàm solve trả về.
Olympic Tin học Châu Á - Thái Bình Dương 2024 (APIO 2024), bài September. Đề và gói bài chính thức: APIO 2024 Tasks.
Vào năm 2992, phần lớn công việc đã do robot đảm nhận. Vì thế, nhiều người có rất nhiều thời gian rảnh, và gia đình bạn cũng vậy: họ vừa quyết định thực hiện một chuyến du hành giữa các hành tinh!
Có \(N\) hành tinh có thể đến, được đánh số từ \(0\) đến \(N-1\), cùng \(M\) tuyến tàu liên hành tinh. Tuyến tàu \(i\) (\(0 \le i < M\)) khởi hành từ hành tinh \(X[i]\) vào thời điểm \(A[i]\), đến hành tinh \(Y[i]\) vào thời điểm \(B[i]\) và có giá vé \(C[i]\).
Tàu là phương tiện duy nhất để di chuyển giữa các hành tinh. Vì vậy, bạn chỉ có thể xuống tàu tại hành tinh đích, và chuyến tàu tiếp theo phải khởi hành từ chính hành tinh đó; việc chuyển tuyến không tốn thời gian.
Một dãy tuyến tàu \(q[0],q[1],\ldots,q[P]\) là hợp lệ khi và chỉ khi, với mọi \(1 \le k \le P\):
và
Du hành giữa các hành tinh mất nhiều thời gian, và ngoài tiền vé tàu, chi phí ăn uống cũng rất đáng kể. May thay, các chuyến tàu liên hành tinh cung cấp thức ăn miễn phí không giới hạn. Cụ thể, nếu bạn đi tuyến tàu \(i\), tại bất kỳ thời điểm nào từ \(A[i]\) đến \(B[i]\), kể cả hai đầu mút, bạn có thể dùng miễn phí bao nhiêu bữa ăn tùy ý. Tuy nhiên, khi gia đình bạn ở trên một hành tinh \(i\) để chờ chuyến tàu tiếp theo, mỗi bữa ăn có giá \(T[i]\).
Gia đình bạn cần dùng \(W\) bữa ăn. Bữa ăn thứ \(i\) (\(0 \le i < W\)) có thể được dùng tức thời tại bất kỳ thời điểm nào trong đoạn từ \(L[i]\) đến \(R[i]\), kể cả hai đầu mút.
Tại thời điểm \(0\), gia đình bạn đang ở hành tinh \(0\). Hãy tính tổng chi phí nhỏ nhất để đến hành tinh \(N-1\). Nếu không thể đến đó, câu trả lời là \(-1\).
Bạn cần cài đặt hàm sau:
long long solve(int N, int M, int W, std::vector<int> T,
std::vector<int> X, std::vector<int> Y,
std::vector<int> A, std::vector<int> B, std::vector<int> C,
std::vector<int> L, std::vector<int> R);
Hàm phải trả về chi phí nhỏ nhất để đi từ hành tinh \(0\) đến hành tinh \(N-1\) nếu có thể đến được, và trả về \(-1\) nếu không thể.
Với mỗi trường hợp kiểm thử, hàm này được gọi đúng một lần.
Ví dụ 1
Xét lời gọi:
solve(3, 3, 1, {20, 30, 40}, {0, 1, 0}, {1, 2, 2},
{1, 20, 18}, {15, 30, 40}, {10, 5, 40}, {16}, {19})
Một cách đến hành tinh \(N-1\) là đi tuyến tàu \(0\), sau đó đi tuyến tàu \(1\), với tổng chi phí \(45\):
| Thời điểm | Hành động | Chi phí |
|---|---|---|
| \(1\) | Lên tuyến tàu \(0\) tại hành tinh \(0\) | \(10\) |
| \(15\) | Đến hành tinh \(1\) | |
| \(16\) | Dùng bữa ăn \(0\) tại hành tinh \(1\) | \(30\) |
| \(20\) | Lên tuyến tàu \(1\) tại hành tinh \(1\) | \(5\) |
| \(30\) | Đến hành tinh \(2\) |
Một cách tốt hơn là chỉ đi tuyến tàu \(2\), với tổng chi phí \(40\):
| Thời điểm | Hành động | Chi phí |
|---|---|---|
| \(18\) | Lên tuyến tàu \(2\) tại hành tinh \(0\) | \(40\) |
| \(19\) | Dùng bữa ăn \(0\) trên tuyến tàu \(2\) | |
| \(40\) | Đến hành tinh \(2\) |
Với hành trình này, dùng bữa ăn \(0\) vào thời điểm \(18\) cũng hợp lệ.
Hàm trả về 40.
Ví dụ 2
Xét lời gọi:
solve(3, 5, 6, {30, 38, 33}, {0, 1, 0, 0, 1}, {2, 0, 1, 2, 2},
{12, 48, 26, 6, 49}, {16, 50, 28, 7, 54},
{38, 6, 23, 94, 50}, {32, 14, 42, 37, 2, 4},
{36, 14, 45, 40, 5, 5})
Hành trình tối ưu là đi tuyến tàu \(0\) với giá vé \(38\). Bữa ăn \(1\) có thể được dùng miễn phí trên tàu. Các bữa ăn \(0\), \(2\) và \(3\) phải mua trên hành tinh \(2\), với chi phí \(33 \times 3=99\). Các bữa ăn \(4\) và \(5\) phải mua trên hành tinh \(0\), với chi phí \(30 \times 2=60\).
Tổng chi phí là:
Hàm trả về `197`.
Trình chấm mẫu đọc dữ liệu theo định dạng sau:
Trình chấm mẫu in trên dòng đầu tiên giá trị do hàm solve trả về.
Olympic Tin học Châu Á - Thái Bình Dương 2024 (APIO 2024), bài Train. Đề và gói bài chính thức: APIO 2024 Tasks.
Alice và Bob là những nhà ảo thuật nổi tiếng. Catherine, một người phụ nữ giàu có rất yêu thích các màn trình diễn tuyệt vời của họ, tuyên bố rằng cô sẽ tặng họ một khối tài sản lớn nếu họ thực hiện được trò ảo thuật sau:
cạnh, rồi đưa các cạnh còn lại cho Bob.
Alice và Bob không nghĩ mình đủ thông minh để luôn biểu diễn thành công trò ảo thuật này, nên họ cần bạn giúp đỡ. Hãy viết chương trình cài đặt chiến lược của Alice và chiến lược của Bob để họ vượt qua thử thách của Catherine.
Bạn cần nộp hai tệp chương trình riêng biệt, Alice.cpp và Bob.cpp. Hai chiến lược không thể truyền thông tin cho nhau bằng biến toàn cục hoặc trạng thái dùng chung.
Chương trình của Alice
Tệp Alice.cpp cài đặt chiến lược của Alice và phải khai báo thư viện Alice.h bằng chỉ thị tiền xử lý #include. Bạn cần cài đặt hàm:
std::vector<std::pair<int, int>> Alice();
vector các cặp biểu diễn các cạnh của cây mà Alice tạo ở bước \(3\).Hàm Alice() phải gọi hàm sau đúng một lần:
long long setN(int n);
Alice dùng lời gọi này để chọn tham số \(n\) đã nói cho Catherine ở bước \(1\). Hàm setN trả về giá trị \(X\) mà Catherine nói cho Alice ở bước \(2\).
Chương trình của Bob
Tệp Bob.cpp cài đặt chiến lược của Bob và phải khai báo thư viện Bob.h bằng chỉ thị tiền xử lý #include. Bạn cần cài đặt hàm:
long long Bob(std::vector<std::pair<int, int>> V);
Alice().Trình tự lời gọi và giá trị trả về trong ví dụ là:
| Lời gọi | Giá trị trả về |
|---|---|
Trình chấm gọi Alice() |
— |
Alice() gọi setN(4) |
3 |
Alice() kết thúc |
{{1, 2}, {2, 3}, {2, 4}} |
Trình chấm gọi Bob({{1, 2}, {2, 4}}) |
3 |
Ví dụ này biểu diễn kịch bản sau:
{{1, 2}, {2, 3}, {2, 4}}, rồi đưa cây cho Catherine.{{1, 2}, {2, 4}} cho Bob.Trình chấm mẫu đọc ở dòng đầu tiên một giá trị \(T\), trong đó \(T \in \{1,2\}\).
Nếu \(T=1\):
Alice() rồi in kết quả theo định dạng:Nếu \(T=2\):
với $n$ là số đỉnh và $m$ là số cạnh còn lại.
Bob() rồi in \(X\) trên dòng đầu tiên.Olympic Tin học Châu Á - Thái Bình Dương 2024 (APIO 2024), bài Magic Show. Đề và gói bài chính thức: APIO 2024 Tasks.