| # | Bài tập | Điểm | Thời gian: | Giới hạn bộ nhớ |
|---|---|---|---|---|
| 1 | BOI 2023 - Minequake | 100 (p) | 1.0s | 768M |
| 2 | BOI 2023 - Staring Contest | 100 (p) | 1.0s | 768M |
| 3 | BOI 2023 - Tycho | 100 (p) | 1.0s | 768M |
Những xưởng bia nhỏ hoàn toàn tự động được lắp đặt trong các khu mỏ bỏ hoang của người lùn ở Moravia thực sự là minh chứng cho sự khéo léo và tài nghệ kỹ thuật của họ! Tiếc thay, đôi khi động đất làm rung chuyển các khu mỏ, khiến các ống dẫn và phễu bị lệch, làm thứ chất lỏng quý giá tràn xuống sàn. Với cương vị Người bảo hộ tối cao về an toàn xưởng bia, bạn có trách nhiệm tắt máy móc trong mọi gian hầm khi xảy ra động đất.
Việc đi qua các đường hầm mất thời gian, nên bạn chắc chắn sẽ đến muộn ở nhiều máy. Điều này không thể tránh khỏi, nhưng bạn muốn giảm thiểu tổng lượng chất lỏng bị tràn.
Khu mỏ của người lùn gồm \(n\) gian hầm được nối bởi \(n-1\) đường hầm. Toàn bộ hệ thống liên thông, nghĩa là có thể đi từ bất kỳ gian hầm nào đến mọi gian hầm khác. Đi qua một đường hầm mất \(1\) đơn vị thời gian. Việc tắt máy móc và di chuyển bên trong một gian hầm không mất thời gian. Tại mỗi gian hầm, nếu tắt máy móc ở thời điểm \(t\) kể từ khi động đất xảy ra thì có \(t\) lít chất lỏng bị tràn.
Chỉ có đúng một trận động đất, tác động đồng thời đến tất cả các gian hầm, và bạn không được tắt bất kỳ máy nào trước khi động đất xảy ra. Bạn có thể bắt đầu ở bất kỳ gian hầm nào.
Dòng đầu tiên chứa số nguyên \(n\), là số gian hầm. Các gian hầm được đánh số từ \(1\) đến \(n\).
\(n-1\) dòng tiếp theo, mỗi dòng chứa hai số nguyên \(u\) và \(v\) cách nhau bằng dấu cách, thỏa mãn \(1\le u<v\le n\), cho biết có một đường hầm nối gian \(u\) với gian \(v\).
In một số nguyên duy nhất: lượng chất lỏng bị tràn ít nhất, tính bằng lít.
Các bộ kiểm thử được chia thành các nhóm, mỗi nhóm có một số điểm. Để nhận được điểm của một nhóm, chương trình phải giải đúng tất cả các bộ kiểm thử trong nhóm đó. Điểm cuối cùng là điểm cao nhất của một lần nộp bài.
Ví dụ 1
3
1 2
2 3
3
Trong ví dụ 1, khu mỏ có dạng như sau:
Nếu bắt đầu ở gian \(2\) và đi theo thứ tự \(2,1,2,3\), bạn có thể tắt máy móc tại thời điểm \(0\) ở gian \(2\), thời điểm \(1\) ở gian \(1\) và thời điểm \(3\) ở gian \(3\). Tổng cộng có \(0+1+3=4\) lít chất lỏng bị tràn. Nếu thay vào đó bắt đầu ở gian \(1\) và đi theo thứ tự \(1,2,3\), tổng lượng chất lỏng bị tràn là \(0+1+2=3\) lít, tốt hơn phương án trước.
Ví dụ 2
4
1 2
1 3
1 4
7
Ví dụ 3
1
0
Thi nhìn là một cuộc đấu kinh điển về khả năng giữ bình tĩnh: hai người nhìn vào mắt nhau trong khi giữ nét mặt điềm nhiên, tự tin. Mục tiêu là duy trì giao tiếp bằng mắt lâu hơn đối thủ. Cuộc đấu kết thúc khi một người mất bình tĩnh, thường là do nhìn đi chỗ khác, mỉm cười, nói chuyện hoặc bật cười.
Là huấn luyện viên đội tuyển quốc gia môn thi nhìn, bạn cần xác định khả năng giữ bình tĩnh của từng người trong số \(n\) thành viên để chuẩn bị cho vòng chung kết thế giới sắp tới. Vận động viên thứ \(i\) có thể duy trì giao tiếp bằng mắt trong đúng \(a_i\) giây, nhưng ban đầu bạn chưa biết các giá trị này. Chẳng hạn, đội của bạn có thể gồm \(n=3\) thành viên:
| \(i\) | Tên | \(a_i\) |
|---|---|---|
| \(1\) | Anna | \(431\) |
| \(2\) | Esther | \(623\) |
| \(3\) | Tony | \(121\) |
Khi vận động viên \(i\) và \(j\) thi đấu, cuộc đối đầu kéo dài đúng \(\min(a_i,a_j)\) giây. Khi đó, người yếu hơn mất bình tĩnh và cả hai bắt đầu mỉm cười, bật cười gần như ngay lập tức. Chẳng hạn, nếu Anna thi đấu với Esther thì cuộc đấu kéo dài \(431\) giây. Điều quan trọng là người quan sát bên ngoài không thể xác định ai thực sự thắng cuộc đối đầu (trong trường hợp này là Esther), mà chỉ đo được thời lượng cuộc đấu.
Mục tiêu của bạn là ước lượng các giá trị \(a_1,\ldots,a_n\) bằng ít cuộc đấu nhất có thể. Rõ ràng không thể xác định được sức mạnh của vận động viên mạnh nhất, nên bạn được phép ước lượng thấp hơn giá trị thực đối với một trong các \(a_i\).
Bài này sử dụng giao diện hàm C++17. Hãy nộp mã nguồn có #include "staringcontest.h" và cài đặt hàm sau; tệp tiêu đề staringcontest.h được cung cấp kèm bài:
std::vector<int> estimate_skills(int n);
Bộ chấm gọi estimate_skills(n) đúng một lần cho mỗi bộ kiểm thử, với \(n\) là số vận động viên. Trong khi thực hiện hàm này, bạn có thể gọi hàm do bộ chấm cung cấp:
int stare(int i, int j);
Mỗi lần gọi stare(i, j) tổ chức một cuộc đấu và trả về \(\min(a_i,a_j)\) dưới dạng int. Hai chỉ số được đánh số từ 1, phải thỏa mãn \(1\le i,j\le n\) và \(i\ne j\). Bạn được phép hỏi lại cùng một cặp; mỗi lần gọi vẫn tính là một truy vấn. Bộ chấm không thích nghi: các giá trị \(a_1,\ldots,a_n\) đã được xác định trước khi gọi estimate_skills.
Để kết thúc, estimate_skills phải trả về một std::vector<int> gồm đúng \(n\) giá trị ước lượng \(b_1,\ldots,b_n\), theo thứ tự vận động viên: phần tử ở chỉ số i - 1 chứa \(b_i\). Bài nộp đúng nếu \(b_i=a_i\) với mọi vận động viên \(i\), ngoại trừ nhiều nhất một người mà bạn được phép ước lượng thấp hơn. Chính xác hơn, phải có \(b_i\le a_i\) với mọi \(1\le i\le n\), và được phép có \(b_k\ne a_k\) với nhiều nhất một chỉ số \(k\). Không có cận dưới bổ sung cho các ước lượng kiểu int; một giá trị âm được phép nếu toàn bộ đáp án vẫn thỏa mãn quy tắc này. Không bắt buộc phải gọi stare nếu bạn đã có đáp án đúng. Trả về đáp án không tính là một truy vấn.
Không cài đặt main, không đọc stdin, không ghi stdout và không chèn mã nguồn bộ chấm vào bài nộp. Chỉ gọi stare trong lúc estimate_skills đang chạy. Chỉ số không hợp lệ, hai chỉ số bằng nhau hoặc lời gọi sau khi đã dùng \(3000\) truy vấn làm bộ chấm kết thúc chương trình ngay lập tức và bộ kiểm thử nhận \(0\) điểm; lời gọi đó không trả về giá trị báo lỗi và không ném ngoại lệ để bạn bắt. Trả về vector sai kích thước, có ước lượng lớn hơn giá trị thật hoặc có hơn một ước lượng thấp hơn cũng khiến bộ kiểm thử nhận \(0\) điểm. Sau khi hàm trả về, bộ chấm kiểm tra đáp án, tính điểm rồi kết thúc chương trình; bạn không cần gọi hàm kết thúc nào khác.
Giới hạn thực tế của bộ chấm: bạn phải trả về đáp án sau nhiều nhất 2999 lần gọi stare. Lần gọi thứ \(3000\) với chỉ số hợp lệ vẫn trả về thời lượng cuộc đấu, nhưng sau đó đáp án trả về từ estimate_skills bị từ chối và bộ kiểm thử nhận \(0\) điểm. Lần gọi thứ \(3001\) bị từ chối ngay lập tức. Quy tắc này áp dụng cho mọi nhóm kiểm thử.
stare, như giải thích ở trên.Các bộ kiểm thử được chia thành các nhóm, mỗi nhóm có một số điểm. Để nhận được điểm của một nhóm, chương trình phải giải đúng tất cả các bộ kiểm thử trong nhóm đó. Điểm cuối cùng là điểm cao nhất của một lần nộp bài.
Đối với nhóm 3, điểm của nhóm là điểm nhỏ nhất trong các bộ kiểm thử của nhóm. Điểm của mỗi bộ kiểm thử phụ thuộc vào số truy vấn đã dùng; dùng càng ít càng tốt. Công thức công bố ban đầu dưới đây dùng \(q\) là số truy vấn và giả sử đáp án đúng:
Ví dụ tính điểm ban đầu: với \(n=1500\) và \(q=3000\), công thức cho \(30\) điểm. Tuy nhiên, bộ chấm dùng ở đây từ chối đáp án ở \(q=3000\), nên trường hợp này thực tế nhận \(0\) điểm. Với \(n=1500\) và \(q=2999\), một đáp án đúng được chấp nhận và nhận \(30\) điểm. Do đó, công thức trên chỉ được áp dụng cho các đáp án hợp lệ với \(q\le 2999\); từ \(3000\) truy vấn trở lên, bộ kiểm thử luôn nhận \(0\) điểm.
Trong bản ghi dưới đây, Bộ chấm gọi: chỉ lời gọi hàm của bạn; Bạn gọi: chỉ lời gọi stare; Bộ chấm trả về: chỉ kết quả của lời gọi đó; Bạn trả về: chỉ vector trả về cuối cùng của estimate_skills, viết theo cú pháp C++. Các nhãn chỉ để minh họa, không phải dữ liệu cần đọc hoặc in.
Ví dụ gọi hàm 1
Bộ chấm gọi: estimate_skills(3)
Bạn gọi: stare(1, 2)
Bộ chấm trả về: 431
Bạn gọi: stare(1, 3)
Bộ chấm trả về: 121
Bạn gọi: stare(3, 2)
Bộ chấm trả về: 121
Bạn trả về: {431, 431, 121}
Ví dụ gọi hàm này là một cách tương tác có thể xảy ra với đội tuyển được mô tả ở trên. Sức mạnh của Anna và Tony được xác định chính xác. Sức mạnh của Esther thì không thể xác định được.
Xe thám hiểm hành tinh Tycho VIII cần trở về căn cứ sau khi thu thập các mẫu khoáng sản. Tycho di chuyển theo một đường thẳng từ vị trí \(0\) đến căn cứ ở vị trí \(b\). Khi di chuyển, xe tiến chậm nhưng đều với tốc độ \(1\) đơn vị mỗi giây. Mỗi giây, Tycho chịu \(1\) đơn vị tổn hại do điều kiện môi trường khắc nghiệt trên hành tinh.
Tình hình còn tệ hơn bởi bức xạ từ một sao xung gần đó: cứ mỗi \(p\) giây, bức xạ lại gây thêm \(d\) đơn vị tổn hại. Tuy nhiên, xe có thể tránh tổn hại do bức xạ bằng cách trú tại một trong \(n\) chỗ trú ẩn dọc đường, chẳng hạn như hang động, thảm thực vật, những tảng đá lớn hoặc xác các loài động vật khổng lồ trên hành tinh. Tycho có thể chọn đứng yên ở bất kỳ vị trí nào trong một số nguyên giây tùy ý.
Vị trí xuất phát \(0\) và căn cứ tại \(b\) đều có che chắn, nên Tycho không chịu tổn hại do bức xạ khi ở đó.
Tổng mức tổn hại nhỏ nhất mà Tycho phải chịu trên đường trở về căn cứ là bao nhiêu?
Dòng đầu tiên chứa bốn số nguyên \(b\), \(p\), \(d\), \(n\) cách nhau bằng một dấu cách: vị trí căn cứ, chu kỳ phát xung của sao xung, mức tổn hại bổ sung do bức xạ của mỗi lần phát xung và số chỗ trú ẩn.
\(n\) dòng tiếp theo, mỗi dòng chứa một số nguyên, lần lượt là các vị trí trú ẩn \(a_1,\ldots,a_n\), thỏa mãn \(0<a_1<\cdots<a_n<b\).
In một số nguyên duy nhất: tổng mức tổn hại nhỏ nhất mà Tycho phải chịu để đến được vị trí \(b\).
Các bộ kiểm thử được chia thành các nhóm, mỗi nhóm có một số điểm. Để nhận được điểm của một nhóm, chương trình phải giải đúng tất cả các bộ kiểm thử trong nhóm đó. Điểm cuối cùng là điểm cao nhất của một lần nộp bài.
Ví dụ 1
18 4 5 2
8
15
29
Xét trường hợp căn cứ ở vị trí \(18\) và có các chỗ trú ẩn ở vị trí \(8\) và \(15\).
Giả sử chu kỳ của sao xung là \(4\), nên Tycho sẽ chịu tổn hại do bức xạ tại các thời điểm \(4,8,12,\ldots\) nếu không được che chắn. Nếu Tycho rời vị trí xuất phát có che chắn vào thời điểm \(0\), xe có thể đến chỗ trú ẩn đầu tiên sau \(8\) giây, chịu \(d\) đơn vị tổn hại do bức xạ tại thời điểm \(4\) nhưng không chịu tổn hại do bức xạ tại thời điểm \(8\) vì đang ở chỗ trú ẩn. Nếu tiếp tục đi mà không dừng lại, xe đến căn cứ tại thời điểm \(18\), chịu thêm \(d+d\) đơn vị tổn hại do bức xạ tại các thời điểm \(12\) và \(16\). Theo cách này, xe chịu \(d+d+d=3d\) đơn vị tổn hại do bức xạ và \(18\) đơn vị tổn hại do môi trường.
Nếu thay vào đó Tycho chờ \(1\) giây ở chỗ trú ẩn thứ hai, tại vị trí \(15\), xung phát ra vào thời điểm \(16\) không gây tổn hại cho xe. Xe đến căn cứ tại thời điểm \(19\), với tổng mức tổn hại là \(2d+19\). Phương án này tốt hơn với phần lớn các giá trị của \(d\). Hai tình huống được minh họa dưới đây:
Ví dụ 2
18 4 0 2
8
15
18
Ví dụ 3
18 10 100 2
8
15
20
Vẫn với căn cứ ở vị trí \(18\) và các chỗ trú ẩn ở vị trí \(8\) và \(15\), nếu chu kỳ của sao xung là \(10\), Tycho có thể chờ \(2\) giây tại vị trí xuất phát rồi đi thẳng về căn cứ mà không dừng lại ở bất kỳ chỗ trú ẩn nào. Như vậy, xe đi qua chỗ trú ẩn thứ nhất, tại vị trí \(8\), đúng lúc sao xung phát xung và đến căn cứ vào thời điểm \(20\). Xe chịu tổng cộng \(20\) đơn vị tổn hại do môi trường và không chịu tổn hại do bức xạ.
Ví dụ 4
18 4 100 0
418
Ví dụ 5
65 20 100 3
14
25
33
172