Gần đây tại Puzzling.SE, có một vấn đề mà tôi đã viết về việc xác định hai chai nào trong số lớn hơn bị nhiễm độc khi chất độc chỉ kích hoạt nếu cả hai thành phần đều say. Nó đã kết thúc khá khó khăn, với hầu hết mọi người quản lý để đưa nó xuống tới 18 hoặc 19 tù nhân bằng các thuật toán hoàn toàn khác nhau.
Báo cáo vấn đề ban đầu như sau:
Bạn là người cai trị một vương quốc thời trung cổ, người thích ném tiệc. Cận thần đã cố gắng đầu độc một trong những chai rượu của bạn lần trước đã rất tức giận khi biết rằng bạn đã xác định được chai nào mà anh ta đã đầu độc trong số 1.000 chỉ với mười tù nhân.
Lần này anh ấy có một chút khéo léo hơn. Anh ta đã phát triển một chất độc hỗn hợp
P
: một chất lỏng nhị phân chỉ gây chết người khi hai thành phần vô hại riêng lẻ trộn lẫn; điều này tương tự như cách epoxy hoạt động. Anh ấy đã gửi cho bạn một thùng 1.000 chai rượu vang khác. Một chai có thành phầnC_a
và một chai khác có thành phầnC_b
. (P = C_a + C_b
)Bất cứ ai uống cả hai thành phần sẽ chết vào đột quỵ vào nửa đêm vào đêm họ uống thành phần cuối cùng, bất kể khi nào trong ngày họ thấm chất lỏng. Mỗi thành phần độc hại tồn tại trong cơ thể cho đến khi thành phần thứ hai kích hoạt, vì vậy nếu bạn uống một thành phần một ngày và thành phần khác vào ngày hôm sau, bạn sẽ chết vào nửa đêm vào cuối ngày thứ hai.
Bạn có hai ngày trước bữa tiệc tiếp theo của bạn. Số lượng tù nhân tối thiểu bạn cần sử dụng để thử nghiệm là bao nhiêu để xác định hai chai nào bị nhiễm độc, và bạn cần tuân theo thuật toán nào với số tù nhân đó?
Phần thưởng
Ngoài ra, giả sử rằng bạn có giới hạn cố định là 20 tù nhân theo ý của bạn, số lượng chai tối đa bạn có thể kiểm tra về mặt lý thuyết và đưa ra kết luận chính xác về việc chai nào bị ảnh hưởng?
Nhiệm vụ của bạn là xây dựng một chương trình để giải quyết vấn đề tiền thưởng. Đối với các n
tù nhân, chương trình của bạn sẽ đưa ra một lịch trình thử nghiệm để có thể phát hiện hai chai bị nhiễm độc trong số các m
chai, nơi m
càng lớn càng tốt.
Chương trình của bạn ban đầu sẽ lấy đầu vào là số N
, số tù nhân. Sau đó nó sẽ xuất ra:
M
, số lượng chai bạn sẽ cố gắng kiểm tra. Những chai sẽ được dán nhãn từ1
đếnM
.N
dòng, chứa nhãn của các chai mỗi tù nhân sẽ uống.
Chương trình của bạn sau đó sẽ lấy đầu vào mà tù nhân đã chết vào ngày đầu tiên, với tù nhân ở dòng đầu tiên 1
, dòng tiếp theo 2
, v.v. Sau đó, nó sẽ xuất ra:
N
nhiều dòng hơn, chứa nhãn của các chai mỗi tù nhân sẽ uống. Những tù nhân chết sẽ có những dòng trống.
Chương trình của bạn sau đó sẽ lấy đầu vào là tù nhân đã chết vào ngày thứ hai và xuất ra hai số, A
và B
, đại diện cho hai chai mà chương trình của bạn nghĩ có chứa chất độc.
Một ví dụ đầu vào cho hai tù nhân và bốn chai có thể đi như vậy, nếu chai 1
và 3
bị nhiễm độc:
> 2 // INPUT: 2 prisoners
4 // OUTPUT: 4 bottles
1 2 3 // OUTPUT: prisoner 1 will drink 1, 2, 3
1 4 // OUTPUT: prisoner 2 will drink 1, 4
> 1 // INPUT: only the first prisoner died
// OUTPUT: prisoner 1 is dead, he can't drink any more bottles
3 // OUTPUT: prisoner 2 drinks bottle 3
> 2 // INPUT: prisoner 2 died
1 3 // OUTPUT: therefore, the poisoned bottles are 1 and 3.
The above algorithm may not actually work in all
cases; it's just an example of input and output.
Lịch trình thử nghiệm của chương trình của bạn phải xác định thành công từng cặp chai bị nhiễm độc có thể để nó là một đệ trình hợp lệ.
Chương trình của bạn sẽ được chấm theo các tiêu chí sau, theo thứ tự:
Số lượng chai tối đa nó có thể nhận thấy cho trường hợp
N = 20
.Số lượng chai cho các trường hợp
N = 21
, và liên tiếp các trường hợp cao hơn sau đó.Độ dài của mã. (Mã ngắn hơn sẽ thắng.)