| # | Bài tập | Điểm | Thời gian: | Giới hạn bộ nhớ |
|---|---|---|---|---|
| 1 | JOI 2016 - Dungeon 2 | 100 (p) | 8.0s | 256M |
| 2 | JOI 2016 - Sushi | 100 (p) | 9.0s | 256M |
| 3 | JOI 2016 - Telegraph | 100 (p) | 1.0s | 256M |
Bạn có biết công ty Just Ordinary Inventions không? Công việc của công ty này là tạo ra những “phát minh hết sức bình thường” (just ordinary inventions).
JOI đang chơi trò chơi mới nhất do công ty Just Ordinary Inventions phát triển.
Trong trò chơi này, người chơi khám phá một hầm ngục gồm một số căn phòng và các con đường. Mỗi con đường nối hai căn phòng khác nhau và có thể đi theo cả hai chiều. Giữa hai căn phòng khác nhau có nhiều nhất một con đường, và không có con đường nào có hai đầu là cùng một phòng. Có thể đi từ bất kỳ phòng nào đến bất kỳ phòng nào khác bằng một số con đường. Các phòng trông rất giống nhau: chỉ nhìn vào căn phòng thì hoàn toàn không thể phân biệt hai phòng có cùng số con đường đi ra.
Để hỗ trợ người chơi, mỗi phòng có một dấu mốc và một bệ đặt đá quý. Dựa vào dấu mốc, người chơi có thể đánh số các con đường đi ra từ phòng đó là \(1, 2, \ldots\). Cấu trúc hầm ngục không thay đổi trong suốt trò chơi, nên đi theo con đường có cùng số thứ tự từ cùng một phòng luôn dẫn đến cùng một phòng đích. Trên bệ có một viên đá quý mà người chơi có thể đổi màu. Màu của viên đá là một trong các màu \(1, 2, \ldots, X\). Khi trò chơi bắt đầu, đá quý trong mọi phòng đều có màu \(1\). Màu của chúng chỉ thay đổi khi người chơi chủ động đổi màu.
JOI nhận ra rằng nếu biết cấu trúc hầm ngục, tức là biết các phòng được nối với nhau như thế nào, thì sẽ dễ dàng chinh phục trò chơi. Tuy nhiên, dù thử nhiều cách, JOI vẫn không xác định được cấu trúc đó. Bạn quyết định viết một chương trình giúp JOI khám phá hầm ngục.
Hãy viết chương trình khám phá và xác định cấu trúc hầm ngục. Tuy nhiên, JOI không muốn được tiết lộ toàn bộ cấu trúc. Vì vậy, thay vì trả lời trực tiếp cấu trúc hầm ngục, với mỗi số nguyên \(i\) từ \(1\) đến \(R\), chương trình phải trả lời số cặp phòng có số con đường ít nhất cần đi qua để di chuyển giữa chúng bằng đúng \(i\). Hai cặp chỉ khác nhau ở thứ tự hai phòng được xem là cùng một cặp.
Thư viện được cung cấp cho phép thực hiện các thao tác sau:
Bạn phải viết một chương trình thực hiện việc trả lời cho JOI. Chương trình phải bao gồm tệp tiêu đề dungeon2.h:
#include "dungeon2.h"
void Inspect(int R);
Hàm này được gọi đúng một lần khi bắt đầu. Tham số R cho biết chương trình phải trả lời số cặp phòng có khoảng cách ngắn nhất bằng \(i\) với mỗi số nguyên \(i\) từ \(1\) đến \(R\). Thứ tự hai phòng trong một cặp không quan trọng.
void Answer(int D, int A);
Lời gọi này trả lời rằng có \(A\) cặp phòng mà số con đường ít nhất cần đi qua để di chuyển giữa hai phòng bằng đúng \(D\).
Các lời gọi Answer phải thỏa mãn mọi điều kiện sau:
| Điều kiện | Phản hồi nếu vi phạm |
|---|---|
D là số nguyên từ \(1\) đến \(R\). |
Wrong Answer [1] |
Không gọi Answer từ hai lần trở lên với cùng giá trị D. |
Wrong Answer [2] |
Phải gọi Answer đúng \(R\) lần. |
Wrong Answer [3] |
A phải đúng bằng số cặp phòng có khoảng cách ngắn nhất bằng D. |
Wrong Answer [4] |
Nếu một lời gọi Answer bị đánh giá là sai, không có gì bảo đảm rằng chương trình sẽ tiếp tục được thực thi.
void Move(int I, int C);
Trước tiên, đổi viên đá quý trong phòng hiện tại, trước khi di chuyển sang màu C. Sau đó, người chơi đi theo con đường thứ I đi ra từ phòng này để đến phòng khác.
Các lời gọi Move phải thỏa mãn mọi điều kiện sau:
| Điều kiện | Phản hồi nếu vi phạm |
|---|---|
Nếu phòng hiện tại có \(K\) con đường đi ra thì I phải là số nguyên từ \(1\) đến \(K\). |
Wrong Answer [5] |
C phải là số nguyên từ \(1\) đến \(X\). Số màu \(X\) được quy định theo từng bài toán con. |
Wrong Answer [6] |
Không được gọi Move quá \(1\,500\,000\) lần. |
Wrong Answer [7] |
Trong tệp dungeon2.h được cung cấp, tham số màu được đặt tên là V, nên khai báo tương ứng là void Move(int I, int V);. Đây vẫn là cùng hàm Move với tham số thứ hai biểu thị màu cần đặt.
int NumberOfRoads();
Trả về số con đường đi ra từ phòng hiện tại.
int LastRoad();
Trả về số thứ tự của con đường vừa được dùng để di chuyển, theo cách đánh số tại phòng hiện tại. Nếu chưa từng gọi Move, hàm trả về \(-1\).
int Color();
Trả về màu viên đá quý trên bệ trong phòng hiện tại.
Sau khi lời gọi Inspect kết thúc, các câu trả lời sẽ được kiểm tra. Bạn được phép cài đặt các hàm phụ và khai báo biến toàn cục để sử dụng nội bộ. Tuy nhiên, chương trình nộp bài không được tương tác với đầu vào chuẩn, đầu ra chuẩn hoặc bất kỳ tệp nào khác bằng bất kỳ cách nào.
Nộp một tệp mã nguồn C++ chứa hàm Inspect và include dungeon2.h được đính kèm theo bài. Không viết hàm main, không đọc đầu vào chuẩn và không ghi đầu ra chuẩn. Hệ thống chấm đặt người chơi ban đầu trong một phòng cố định, cung cấp các hàm Move, NumberOfRoads, LastRoad, Color, Answer, rồi gọi Inspect đúng một lần.
Các ký hiệu \(N, D_i, T_{ij}\) có ý nghĩa như trong phần dữ liệu vào của trình chấm mẫu. Mọi bộ dữ liệu thỏa mãn:
Gọi \(N\) là số phòng và \(M\) là số con đường trong hầm ngục của bộ dữ liệu.
Trong mỗi bộ kiểm thử, gọi \(C\) là số lần gọi Move. Gọi \(L\) là giá trị lớn nhất của tỉ số sau trên tất cả các bộ kiểm thử của bài toán con 3:
Điểm của bài toán con 3 được tính chính xác như sau:
Ở đây, \(\lfloor x \rfloor\) là số nguyên lớn nhất không vượt quá \(x\).
Trên hệ thống chấm, nếu chương trình kết thúc đúng cách và câu trả lời được đánh giá là đúng, cột chi tiết hiển thị Accepted. Tuy nhiên, khi chấm bài toán con 3, đối với một bộ kiểm thử thỏa mãn điều kiện dưới đây, cột kết quả sẽ hiển thị sai, ngay cả khi cột chi tiết hiển thị Accepted:
Dưới đây là một ví dụ dữ liệu vào của trình chấm mẫu và một chuỗi lời gọi hàm tương ứng.
4 3 3
1
2
3
1 3 4
2
2 4
2
2 3
4
2
0
| Lời gọi | Giá trị trả về |
|---|---|
Inspect(3) |
|
NumberOfRoads() |
1 |
LastRoad() |
-1 |
Move(1,2) |
|
Color() |
1 |
LastRoad() |
1 |
NumberOfRoads() |
3 |
Move(1,3) |
|
Color() |
2 |
Answer(1,4) |
|
Answer(2,2) |
|
Answer(3,0) |
Lưu ý rằng các lời gọi trong ví dụ này không nhất thiết là những thao tác có ý nghĩa để giải bài toán.
Nhà hàng sushi băng chuyền JOI vận chuyển các đĩa sushi trên một băng chuyền hình vòng tròn quay ngược chiều kim đồng hồ. Hiện có \(N\) khách, được đánh số từ \(1\) đến \(N\), ngồi quanh băng chuyền theo thứ tự số tăng dần ngược chiều kim đồng hồ. Khách \(N\) ngồi cạnh khách \(1\).
Mỗi khách đang giữ đúng một chiếc đĩa. Mỗi đĩa có một giá trị gọi là giá tiền. Khi rời nhà hàng, mỗi khách phải trả số tiền bằng giá của chiếc đĩa mình đang giữ.
Nhà hàng JOI tổ chức một đợt khuyến mãi đặc biệt. Đầu bếp lần lượt đưa đĩa lên băng chuyền trong \(Q\) lượt. Lượt thứ \(i\) được mô tả bởi ba số nguyên \((S_i,T_i,P_i)\), với \(1 \le i \le Q\).
Ngay trước khi đợt khuyến mãi bắt đầu, đầu bếp thu hết các đĩa đang có trên băng chuyền. Sau đó, với \(i=1,2,\ldots,Q\), lần lượt thực hiện ba bước sau:
Bạn là người học việc của đầu bếp và được giao nhiệm vụ rửa đĩa. Cách rửa đĩa ở nhà hàng JOI phụ thuộc vào giá của đĩa. Để chuẩn bị, bạn muốn biết trước giá của chiếc đĩa mà đầu bếp thu lại trong từng lượt của \(Q\) lượt khuyến mãi.
Bổ sung sau khi kỳ thi kết thúc: Khi \(S_i=T_i\), chỉ khách \(S_i\) thực hiện thao tác ở bước 2.
Cho giá của đĩa mà mỗi khách đang giữ ngay trước đợt khuyến mãi và thông tin của các lượt đưa đĩa lên băng chuyền. Hãy tính giá của chiếc đĩa mà đầu bếp thu lại trong mỗi lượt.
Đọc từ đầu vào chuẩn:
Ghi ra đầu ra chuẩn \(Q\) dòng. Dòng thứ \(i\) chứa một số nguyên là giá của chiếc đĩa mà đầu bếp thu lại trong lượt thứ \(i\), với \(1 \le i \le Q\).
Ví dụ 1
6 7
8
6
7
4
5
9
2 4 5
4 1 4
6 2 7
1 5 2
3 4 8
4 3 1
3 1 3
7
9
8
7
8
6
5
Giá các đĩa mà khách \(1\) đến khách \(6\) đang giữ sau từng lượt lần lượt là:
| Sau lượt | Giá các đĩa theo thứ tự khách |
|---|---|
| 1 | \(8,5,6,4,5,9\) |
| 2 | \(8,5,6,4,4,5\) |
| 3 | \(7,5,6,4,4,5\) |
| 4 | \(2,5,6,4,4,5\) |
| 5 | \(2,5,6,4,4,5\) |
| 6 | \(2,5,5,1,4,4\) |
| 7 | \(2,5,3,1,4,4\) |
Ví dụ 2
4 2
5
2
4
7
1 4 3
1 4 1
7
5
Ví dụ này thỏa mãn các ràng buộc của bài toán con 2.
Ví dụ 3
10 10
19
5
8
17
14
3
9
10
7
6
1 8 4
7 3 2
5 9 10
4 8 3
10 3 6
8 7 4
6 6 3
2 9 12
6 3 7
9 6 3
19
10
14
17
8
10
3
12
7
9
Quần đảo JOI là một quốc đảo nhỏ trên Thái Bình Dương, gồm \(N\) hòn đảo được đánh số từ \(1\) đến \(N\).
Các đảo chủ yếu liên lạc với nhau bằng sóng vô tuyến. Mỗi đảo có một máy phát và một máy thu. Máy phát có thể phát sóng theo mọi hướng, nhưng máy thu chỉ nhận được sóng từ một hướng nhất định. Vì vậy, mỗi máy thu chỉ nhận được sóng từ đúng một đảo cụ thể. Có thể đổi hướng máy thu để thay đổi đảo mà nó nhận sóng.
Hiện tại, máy thu trên đảo \(i\) nhận được sóng từ đảo \(A_i\), với \(A_i \ne i\). Chi phí đổi hướng máy thu trên đảo \(i\) là \(C_i\), không phụ thuộc vào hướng mới, với \(1 \le i \le N\).
Quần đảo JOI cung cấp dịch vụ điện báo như một dịch vụ công. Nếu máy thu trên đảo \(j\) nhận được sóng từ đảo \(i\), với \(1 \le i,j \le N\) và \(i \ne j\), thì có thể gửi điện báo từ đảo \(i\) đến đảo \(j\) qua liên lạc vô tuyến. Điện báo cũng có thể được chuyển tiếp qua một số đảo. Cụ thể, với ba đảo phân biệt \(i,j,k\), nếu có thể gửi điện báo từ \(i\) đến \(j\) và từ \(j\) đến \(k\), thì có thể gửi điện báo từ \(i\) đến \(k\). Không thể gửi điện báo bằng phương thức nào khác ngoài liên lạc vô tuyến.
Là bộ trưởng phụ trách thông tin liên lạc của quần đảo JOI, bạn muốn có thể gửi điện báo từ bất kỳ đảo nào đến bất kỳ đảo nào khác. Để đạt được điều này, có thể cần đổi hướng máy thu trên một số đảo. Tổng chi phí là tổng chi phí đổi hướng của từng máy thu được thay đổi.
Cho số đảo và thông tin về máy thu trên từng đảo. Hãy tính chi phí nhỏ nhất để có thể gửi điện báo từ bất kỳ đảo nào đến bất kỳ đảo nào khác.
Đọc từ đầu vào chuẩn:
Ghi ra đầu ra chuẩn một dòng chứa chi phí nhỏ nhất để có thể gửi điện báo từ bất kỳ đảo nào đến bất kỳ đảo nào khác.
Ví dụ 1
4
2 2
1 4
1 3
3 1
4
Đổi hướng máy thu trên đảo \(2\) để nhận sóng từ đảo \(4\). Khi đó, có thể gửi điện báo từ bất kỳ đảo nào đến bất kỳ đảo nào khác, với chi phí là \(4\).
Không có cách đổi hướng các máy thu nào đạt yêu cầu với chi phí nhỏ hơn \(4\), nên kết quả là \(4\).
Ví dụ 2
4
2 2
1 6
1 3
3 1
5
Trước tiên, đổi hướng máy thu trên đảo \(1\) để nhận sóng từ đảo \(4\). Sau đó, đổi hướng máy thu trên đảo \(3\) để nhận sóng từ đảo \(2\). Khi đó, có thể gửi điện báo từ bất kỳ đảo nào đến bất kỳ đảo nào khác. Tổng chi phí là:
Không có cách đổi hướng các máy thu nào đạt yêu cầu với chi phí nhỏ hơn $5$, nên kết quả là $5$.
Ví dụ 3
4
2 2
1 3
4 2
3 3
4
Chỉ cần đổi hướng máy thu trên đảo \(1\) và đảo \(3\).
Ví dụ 4
3
2 1
3 1
1 1
0
Không cần đổi hướng máy thu trên bất kỳ đảo nào.