เมื่อเร็ว ๆ นี้ที่ Puzzling.SE มีปัญหาที่ฉันเขียนเกี่ยวกับการพิจารณาว่าขวดสองขวดจากจำนวนที่มากกว่านั้นถูกวางยาพิษเมื่อพิษเปิดใช้งานเฉพาะในกรณีที่ส่วนประกอบทั้งสองเมา ในที่สุดมันก็กลายเป็นเรื่องยากลำบากโดยคนส่วนใหญ่จัดการเพื่อให้นักโทษลง 18 หรือ 19 คนโดยใช้อัลกอริทึมที่แตกต่างกันโดยสิ้นเชิง
คำแถลงปัญหาเดิมมีดังต่อไปนี้:
คุณคือผู้ปกครองของอาณาจักรยุคกลางที่ชอบปาร์ตี้ขว้างปา ข้าราชบริพารที่พยายามวางยาพิษขวดไวน์ของคุณครั้งหนึ่งก็โกรธที่จะรู้ว่าคุณจัดการเพื่อระบุขวดที่เขาวางยาพิษจาก 1,000 ขวดกับนักโทษเพียงสิบคน
เวลานี้เขาช่างเก่งขึ้น เขาได้พัฒนาพิษผสม
P
: ของเหลวแบบไบนารีที่อันตรายถึงตายเมื่อส่วนประกอบที่ไม่เป็นอันตรายสองรายการผสมกัน มันคล้ายกับการทำงานของอีพอกซี เขาส่งลังอีก 1,000 ขวดให้คุณ ขวดหนึ่งมีองค์ประกอบและอีกคนหนึ่งมีองค์ประกอบC_a
C_b
(P = C_a + C_b
)ทุกคนที่ดื่มส่วนประกอบทั้งสองจะตายในจังหวะของเที่ยงคืนในตอนกลางคืนพวกเขาดื่มส่วนประกอบสุดท้ายโดยไม่คำนึงถึงว่าเมื่อใดในวันที่พวกเขาดูดของเหลว ส่วนประกอบที่เป็นพิษแต่ละชิ้นจะยังคงอยู่ในร่างกายจนกว่าส่วนประกอบที่สองจะทำงานดังนั้นหากคุณดื่มหนึ่งองค์ประกอบในวันหนึ่งและอีกองค์ประกอบต่อไปคุณจะตายในเวลาเที่ยงคืนในตอนท้ายของวันที่สอง
คุณมีสองวันก่อนงานปาร์ตี้ครั้งต่อไปของคุณ จำนวนผู้ต้องขังขั้นต่ำที่คุณต้องใช้ในการทดสอบคืออะไรเพื่อระบุขวดสองขวดที่เสียและขั้นตอนวิธีใดที่คุณต้องปฏิบัติตามกับจำนวนนักโทษ
โบนัส
นอกจากนี้สมมติว่าคุณมีผู้ต้องขังที่ จำกัด จำนวน 20 คนจำนวนขวดสูงสุดที่คุณสามารถทดสอบได้ในทางทฤษฎีและมาถึงข้อสรุปที่แม่นยำเกี่ยวกับขวดที่ได้รับผลกระทบ
งานของคุณคือสร้างโปรแกรมเพื่อแก้ปัญหาโบนัส ได้รับn
นักโทษโปรแกรมจะประดิษฐ์กำหนดการทดสอบว่าจะสามารถที่จะตรวจสอบทั้งสองขวดยาพิษในหมู่m
ขวดที่m
มีขนาดใหญ่ที่สุดเท่าที่ทำได้
ในตอนแรกโปรแกรมของคุณจะป้อนหมายเลขN
จำนวนนักโทษ จากนั้นจะแสดงผลลัพธ์:
M
จำนวนขวดที่คุณจะพยายามทดสอบ ขวดเหล่านี้จะมีข้อความจากไป1
M
N
บรรทัดที่มีฉลากของขวดนักโทษแต่ละคนจะดื่ม
โปรแกรมของคุณจะใช้เป็นข้อมูลที่นักโทษเสียชีวิตในวันแรกโดยมีนักโทษอยู่ที่บรรทัดแรกบรรทัด1
ถัดไป2
เป็นต้นจากนั้นรายการจะแสดงผลลัพธ์:
N
บรรทัดเพิ่มเติมที่ประกอบด้วยฉลากของขวดแต่ละนักโทษจะดื่ม นักโทษที่ตายจะมีเส้นว่าง
โปรแกรมของคุณจะใช้เป็นข้อมูลที่นักโทษเสียชีวิตในวันที่สองและส่งออกตัวเลขสองจำนวนA
และB
แสดงว่าขวดใดที่โปรแกรมของคุณคิดว่ามีพิษสองขวด
ตัวอย่างอินพุตสำหรับนักโทษสองคนและสี่ขวดอาจเป็นเช่นนี้หากขวด1
และ3
วางยาพิษ:
> 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.
กำหนดการทดสอบโปรแกรมของคุณจะต้องกำหนดขวดที่เป็นพิษแต่ละคู่ที่เป็นไปได้เพื่อให้สามารถส่งได้อย่างถูกต้อง
โปรแกรมของคุณจะได้คะแนนตามเกณฑ์ต่อไปนี้ตามลำดับ:
N = 20
จำนวนสูงสุดของขวดก็สามารถมองเห็นสำหรับกรณีที่จำนวนขวดสำหรับกรณี
N = 21
และกรณีที่สูงขึ้นอย่างต่อเนื่องหลังจากนั้นความยาวของรหัส (รหัสที่สั้นกว่าจะชนะ)