programming.in.th · ข้อ 2010
จับปลาหนึ่งตัวได้ชุดอัญมณีเป็นกล่องหนึ่งใบ แต่ชุดเดียวกันอยู่ได้หลายกล่อง ไล่จากการเพิ่มเข้าตัดออก (25 คะแนน) ไปการให้กล่องหลังสุดเป็นเจ้าของ (70 คะแนน) จนถึงเซกเมนต์ทรีที่เก็บผลคูณ เพราะหารเอาเศษด้วย M แล้วหารกลับไม่ได้
ในทะเลสาบมีปลา F ตัว แต่ละตัวกลืนอัญมณีไว้หนึ่งชิ้น อัญมณีมี K ประเภท
ปลาหลายตัวกินประเภทเดียวกันได้ ปลาตัวหนึ่งกินปลาอีกตัวได้ก็ต่อเมื่อมันยาวอย่างน้อยสองเท่า
ของตัวที่ถูกกิน
เมื่อกินแล้ว อัญมณีในท้องตัวเล็กจะย้ายมาอยู่ในท้องตัวใหญ่ ส่วนความยาวไม่เปลี่ยน เราจับปลาได้หนึ่งตัวและได้อัญมณีในท้องมันทั้งหมด
คำถามคือชุดของอัญมณีที่เป็นไปได้มีกี่แบบ ชุดนับจากจำนวนของแต่ละประเภท ไม่สนใจลำดับ
ตอบเป็นเศษที่เหลือจากการหารด้วย M (การหารเอาเศษนี้ในโค้ดเรียกว่า mod ย่อจาก modulo)
อินพุต / ขอบเขต / เอาต์พุต
F บรรทัดที่ 2 คือ K บรรทัดที่ 3 คือ
M จากนั้น F บรรทัด แต่ละบรรทัดคือความยาวปลาและประเภทอัญมณีที่มันกิน
F ≤ 500,000, K ≤ F, 2 ≤ M ≤ 30,000,
ความยาวปลาไม่เกินหนึ่งพันล้าน และรับประกันว่าอัญมณีมีครบทั้ง K ประเภท
เวลา 3 วินาที หน่วยความจำ 64 เมกะไบต์
MK ไม่เกิน 7,000
และในนั้นมี 25 คะแนนที่ K ไม่เกิน 20 | Input | Output |
|---|---|
| 5 3 7 2 2 5 1 8 3 4 1 2 3 | 4 |
ชุดที่เป็นไปได้มี 11 แบบ คือ [1] [2] [3] [1,2] [1,3] [2,3] [3,3] [1,2,3] [1,3,3] [2,3,3] [1,2,3,3] และ 11 หารเอาเศษด้วย
7 ได้ 4 ตรงกับรายการที่โจทย์ยกมาให้ดูทั้งหมด
ใบ้
ถามก่อนว่า ถ้าเราตั้งใจจะจับปลาตัว X อัญมณีที่ลงไปอยู่ในท้องมันได้มีของใครบ้าง
ปลาที่ X กินตรง ๆ ต้องยาวไม่เกินครึ่งหนึ่งของ X
ส่วนปลาที่ถูกปลาตัวเล็กพวกนั้นกินไปก่อน ยาวไม่เกินครึ่งของ X ด้วยหรือเปล่า
พอตอบข้อนั้นได้ ปัญหาจะกลายเป็นการนับชุดตัวเลข ส่วนที่ยากคือ ชุดเดียวกันเกิดได้จากปลาหลายตัว แล้วเราจะนับมันครั้งเดียวได้ยังไง
ปลาสามตัวสองชนิด พอให้เห็นว่าตัวจับกลืนใครได้บ้าง
เลือกชนิดที่จะจับ ปลาตัวที่ยาวที่สุดของชนิดนั้นจะเป็นตัวจับ
เลือกชนิดที่จะจับก่อน แล้วค่อยปรับจำนวนอัญมณีแต่ละชนิดที่จะเก็บ
เก็บได้ 0 จาก 0 ชุดที่ต่างกัน
ยังไม่ได้เก็บชุดไหนเลย
ถ้าเจอชุดที่เก็บซ้ำ ให้สังเกตว่ามันมาจากการจับคนละชนิดกันได้ นั่นคือจุดที่การนับตรง ๆ จะนับเกิน
เริ่มจากคำถามในใบ้ ถ้าจะจับปลา X ที่ยาว Lx อัญมณีที่ไปอยู่ในท้องมันได้มาจากใครบ้าง
X กินเองได้ ต้องยาวไม่เกิน Lx / 2Lx / 2 กินก่อน
ตัวมันเองยาวไม่เกิน Lx / 4 ซึ่งอยู่ในกลุ่มแรกอยู่แล้ว
X เลือกกินตัวไหนก็ได้ ทีละตัวตามใจ ชุดย่อยแบบไหนของกลุ่มก็ได้ทั้งนั้นสิ่งที่ได้จากปลาหนึ่งตัว
อัญมณีของตัว X เอง บวกกับชุดย่อยใด ๆ ของปลาที่ยาวไม่เกินครึ่งหนึ่งของ X
ดูกับตัวอย่างในโจทย์ ถ้าจับปลายาว 8 (ชนิด 3) ปลาที่ยาวไม่เกิน 4 มี 3 ตัว แต่ละชนิดหยิบได้ดังนี้
ทุกชนิดเลือกจำนวนได้อิสระต่อกัน มีทั้งหมด 2 × 2 × 2 = 8 ชุด
เขียนแบบทั่วไป ถ้าในกลุ่มที่กลืนได้มีปลาชนิด s อยู่ m ตัว ชนิด s หยิบได้ 0 ถึง m ชิ้น
ส่วนชนิดของตัวจับหยิบได้ 1 ถึง m + 1 ชิ้น เพราะชิ้นของตัวจับติดมาเสมอ
ค่าสูงสุด m + 1 นี้ ต่อจากนี้เรียกว่าเพดานของชนิดตัวจับ
ชุดทั้งหมดของตัวจับหนึ่งตัวมีรูปเป็นกล่อง (box) แต่ละด้านคือช่วงของชนิดหนึ่ง และจำนวนชุดในกล่องคือผลคูณของจำนวนค่าที่แต่ละด้านเลือกได้ อย่างที่เพิ่งคูณกันได้ 8
ปลาชนิดเดียวกัน ตัวที่ยาวกว่ากลืนได้ทุกตัวที่ตัวสั้นกว่ากลืนได้ กล่องของมันครอบกล่องของตัวสั้นไว้ทั้งใบ แต่ละชนิดเลยเหลือกล่องเดียว คือกล่องของปลาตัวที่ยาวที่สุดในชนิดนั้น ต่อจากนี้เรียกปลาตัวนั้นว่าตัวแทนของชนิด
ปัญหาที่เหลือ
มีกล่อง K ใบ ใบละชนิด คำตอบคือจำนวนชุดที่อยู่ในกล่องอย่างน้อยหนึ่งใบ
รู้แล้วว่าต้องนับอะไร ลองไล่จากวิธีที่ตรงที่สุดขึ้นไปทีละขั้น แล้วดูว่าแต่ละวิธีไปได้ถึงชุดทดสอบไหน
| ขอบเขต | คะแนนสะสม |
|---|---|
| K ไม่เกิน 20 | 25 |
| K ไม่เกิน 7,000 | 70 |
| ขอบเขตเต็ม K ไม่เกิน 500,000 | 100 |
วิธีที่ 1
เท่าจำนวนชุด ซึ่งโตแบบทวีคูณ
ให้ปลาทุกตัวลองเป็นตัวจับ ไล่ทุกชุดในกล่องของมันลงเซต (set โครงสร้างที่เก็บของแต่ละอย่างได้ครั้งเดียว) แล้วนับของในเซต
ใช้เป็นตัวตรวจ
วิธีที่ 2
ราว 2K × K ก้าว
หาขนาดของกล่องทุกใบรวมกันจากขนาดของส่วนที่ทับกัน ไม่ต้องไล่ทีละชุด
ได้ 25 คะแนน
วิธีที่ 3
ราว K² ก้าว
ตั้งกฎให้ทุกชุดมีกล่องเจ้าของใบเดียว แล้วนับแต่ละชุดที่เจ้าของของมัน (ตอนที่ 3 และ 4)
ได้ 70 คะแนน
วิธีเต็ม
ราว (F + 4K) × log K บวกการเรียง
ต้นไม้ช่วง (segment tree อ่านว่า "เซกเมนต์ทรี") ตอบผลคูณของช่วงได้เร็ว log K คือจำนวนครั้งที่ผ่าครึ่ง K จนเหลือ 1 ได้ราว 19 ที่ K ห้าแสน (ตอนที่ 5)
ได้ครบ 100 คะแนน
วิธีที่ 2 ใช้หลักการเพิ่มเข้าตัดออก (inclusion–exclusion อ่านว่า "อินคลูชัน เอ็กซ์คลูชัน") กับกล่องสองใบ ให้บวกขนาดของทั้งสองใบ แล้วลบส่วนที่ทับกันออกหนึ่งรอบ เพราะชุดในส่วนนั้นถูกบวกไปสองรอบ
กับกล่องสามใบ ให้บวกขนาดทั้งสามใบ ลบส่วนที่ทับกันของทุกคู่ แล้วบวกส่วนที่ทับกันทั้งสามใบคืน ชุดที่อยู่ครบสามใบถูกบวกสามรอบและลบสามรอบ บวกคืนอีกรอบมันก็ถูกนับหนึ่งครั้งพอดี
กล่องสองใบตัดกันแล้วยังเป็นกล่อง ด้านของแต่ละชนิดคือส่วนที่ทับกันของสองช่วง ขนาดของส่วนที่ทับกันคูณออกมาได้ทันที
ตัวอย่างเล็กที่ใช้ตลอดเฉลย
ตัวอย่างในโจทย์เล็กเกินจะเห็นทุกส่วนของสูตร จากนี้ไปใช้ทะเลสาบนี้แทน มีปลา 7 ตัว อัญมณี 4 ชนิด
ตัวแทนของชนิด 1 ถึง 4 ยาว 2, 11, 12, 16 ตามลำดับ ไล่นับตรง ๆ แล้วมีทั้งหมด 27 ชุด
| หยิบชนิด | กล่อง 1 | กล่อง 2 | กล่อง 3 | กล่อง 4 |
|---|---|---|---|---|
| ชนิด 1 | 1 | 0 ถึง 1 | 0 ถึง 1 | 0 ถึง 1 |
| ชนิด 2 | 0 | 1 ถึง 2 | 0 ถึง 1 | 0 ถึง 2 |
| ชนิด 3 | 0 | 0 ถึง 1 | 1 ถึง 2 | 0 ถึง 1 |
| ชนิด 4 | 0 | 0 | 0 | 1 |
| จำนวนชุด | 1 | 8 | 8 | 12 |
แกะสูตรกับกล่อง 2 และกล่อง 3
ถ้ามีกล่องหลายใบ ให้ไล่ทุกกลุ่มของกล่องที่ไม่ว่าง กลุ่มที่มีจำนวนกล่องเป็นเลขคี่ให้บวกส่วนที่ทับกัน เลขคู่ให้ลบ ตัวอย่างเล็กมี 15 กลุ่ม รวมแล้วได้ 27 ตรงกับการไล่นับ
ปัญหาคือจำนวนกลุ่มเท่ากับ 2K ลองเทียบงานของแต่ละวิธีกับงบเวลา คือจำนวนก้าวที่เครื่องทำทันในลิมิต 3 วินาที
คิดเป็นตัวเลข
เป้ามีสองขั้น ขั้นแรกต้องเลิกจ่ายเป็นทวีคูณของ K ด้วยการนับแต่ละชุดครั้งเดียวตั้งแต่ต้น (ตอนที่ 3 และ 4)
ขั้นที่สองต้องลดงานต่อชนิดจากราว K ลงเหลือราว log K (ตอนที่ 5)
ที่มาของแนวคิดนี้
วิธีที่ 2 ช้าเพราะต้องคิดส่วนที่ทับกันของทุกกลุ่มกล่อง ถ้าแต่ละชุดถูกนับครั้งเดียวตั้งแต่แรก ส่วนที่ทับกันก็ไม่ต้องคิดเลย
คำถามเลยเปลี่ยนเป็น ชุดหนึ่งควรถูกนับที่กล่องไหน และกฎนั้นต้องเช็กได้เร็วด้วยตัวเลขไม่กี่ตัว
ในเกม ถ้ากดเก็บชุดที่เคยเก็บแล้ว เกมจะบอกว่าชุดนั้นไปถึงได้จากหลายทาง ตัวอย่างเล็กก็มีแบบนี้
ชุด [2,3] อยู่ทั้งในกล่อง 2 และกล่อง 3
ทางออกคือตั้งกฎให้ทุกชุดมีเจ้าของกล่องเดียว แล้วนับแต่ละชุดที่กล่องเจ้าของเท่านั้น ก่อนตั้งกฎได้ ต้องเรียงกล่องเป็นลำดับก่อน โดยเรียงชนิดตามความยาวของตัวแทนจากสั้นไปยาว ในตัวอย่างเล็ก ลำดับนี้ตรงกับหมายเลขชนิดพอดี
นึกภาพ
แถบในภาพซ้อนกันแบบตุ๊กตาแม่ลูกดก (matryoshka) แถบของแถวล่างครอบแถบของแถวบนไว้ทั้งแถบ ตัวแทนที่ยาวกว่ากลืนได้ทุกตัวที่ตัวแทนที่สั้นกว่ากลืนได้ และอาจกลืนได้เพิ่มอีก
ที่ซ้อนกันคือแถบ ตัวกล่องไม่ได้ซ้อนกัน เพราะกล่องของชนิด j ทุกชุดต้องมีชนิด j อย่างน้อยหนึ่งชิ้น
เช่นกล่อง 1 มีแค่ชุด [1] ซึ่งไม่อยู่ในกล่อง 2 เลย
กฎเจ้าของ
ชุดหนึ่งเป็นของกล่องที่อยู่หลังสุดในลำดับ ในบรรดากล่องที่มีชุดนั้น
แถบที่ซ้อนกันทำให้กฎนี้เช็กง่าย กล่องที่มาหลังกลืนได้ทุกอย่างที่กล่องก่อนกลืนได้
สิ่งที่ต้องดูจึงเหลือสองเรื่อง ซึ่งตอนที่ 4 จะไล่ให้ดู ชุด [2,3] เมื่อกี้เป็นของกล่อง 3
เลือกกล่องของชนิด i มาหนึ่งใบ ชุดในกล่องนี้เป็นของ i เมื่อไม่มีกล่อง j ที่มาหลัง i มีชุดนั้นด้วย
ตลอดตอนนี้จะดูไปพร้อมกับแถวของชนิด 2 ในตัวอย่างเล็ก ซึ่งตัวแทนยาว 11 กลืนปลาได้ถึงยาว 5.5
ได้ m = [1, 1, 1, 0] ตามชนิด 1 ถึง 4
| เงื่อนไข | ผ่านเองเสมอไหม | เหตุผล |
|---|---|---|
| ข้อ 1: ชนิดอื่นที่ไม่ใช่ i และ j ไม่เกินช่วงของกล่อง j | ผ่านเสมอ | ตัวแทนของ j ยาวไม่น้อยกว่าของ i กลืนได้ทุกตัวที่ i กลืนได้ |
| ข้อ 2: ชนิด j ไม่เกินช่วงของกล่อง j | ผ่านเสมอ | ในกล่อง i ชนิด j มีได้ไม่เกินจำนวนที่ i กลืน ซึ่งไม่เกินที่ j กลืน |
| ข้อ 3: ชนิด j มีอย่างน้อยหนึ่งชิ้น | ไม่เสมอ | ทุกชุดในกล่อง j มีชิ้นของตัวจับ ชุดที่มีชนิด j เป็น 0 อยู่ในกล่อง j ไม่ได้ |
| ข้อ 4: ชนิด i ไม่เกินช่วงของกล่อง j | ไม่เสมอ | ในกล่อง i ชนิด i มีชิ้นพิเศษของตัวจับ ถ้าชุดใช้ถึงเพดาน กล่อง j ต้องกลืนปลาชนิด i ได้มากกว่าที่ i กลืนหนึ่งตัว |
ชุดมีชนิด i อยู่ 1 ถึง m ชิ้น กล่องทุกใบที่มาหลังกลืนปลาชนิด i ได้อย่างน้อย m ตัวอยู่แล้ว
ข้อ 4 ผ่านกับทุก j ตัวกันที่เหลือคือข้อ 3 ชุดเป็นของ i ได้เมื่อทุกชนิดที่มาหลังมี 0 ชิ้น
ชนิด i เลือกได้ m แบบ ชนิดที่มาก่อนแต่ละชนิดเลือกได้ 0 ถึง m ของมัน คือ m + 1 แบบ
ผลคูณของ m + 1 ของทุกชนิดที่มาก่อน ต่อจากนี้เรียกว่าก่อนหน้า
สูตรกรณี (ข)
m ของชนิด i × ก่อนหน้า
แถวชนิด 2: 1 × 2 = 2 ชุด คือ [1,2] [2]
ชุดมีชนิด i ครบ m + 1 ชิ้น กล่อง j จะให้ได้ครบต้องกลืนปลาชนิด i เพิ่มจากที่ i กลืนอีกหนึ่งตัว
ปลาชนิด i ที่ตัวแทนของ i ยังกลืนไม่ได้ ตัวที่สั้นที่สุดเรียกว่าx
กล่อง j กลืนปลาชนิด i ได้เพิ่มก็ต่อเมื่อกลืน x ได้
กล่อง j กลืน x ได้เมื่อตัวแทนของ j ยาวอย่างน้อย 2x ชนิดแรกหลัง i ที่ทำได้เรียกว่าJ
ตัวแทนเรียงจากสั้นไปยาวแล้ว ทุกชนิดตั้งแต่ J เป็นต้นไปก็กลืน x ได้หมด
หา J ของแถวชนิด 2
ชนิดตั้งแต่ J ผ่านข้อ 4 ได้ ตัวกันของมันคือข้อ 3 ชนิดพวกนี้ต้องมี 0 ชิ้น
ส่วนชนิดที่อยู่หลัง i แต่ก่อน J ตกข้อ 4 อยู่แล้ว จะมีกี่ชิ้นก็ได้ตามกล่องของ i
ผลคูณของ m + 1 ของชนิดกลุ่มนี้เรียกว่าช่วงกลาง
สูตรกรณี (ก)
ก่อนหน้า × ช่วงกลาง
แถวชนิด 2: ก่อนหน้า 2 × ช่วงกลาง (ชนิด 3) 2 = 4 ชุด
คือ [1,2,2,3] [1,2,2] [2,2,3] [2,2]
ชุดทั้ง 6 ชุดของสองกรณีตรงกับรายการชุดที่กล่อง 2 เป็นเจ้าของจากการไล่นับตรง ๆ ทีนี้ไล่ทุกแถวของตัวอย่างเล็ก กดถัดไปทีละชนิด
กดถัดไปเพื่อไล่ชนิดทีละชนิด
| ชนิด | ตัวแทน | m ทุกชนิด | x | J | (ข) | (ก) |
|---|---|---|---|---|---|---|
| 1 | 2 | 0 0 0 0 | 2 | ชนิด 2 | 0 × 1 = 0 | 1 × 1 = 1 |
| 2 | 11 | 1 1 1 0 | 8 | ชนิด 4 | 1 × 2 = 2 | 2 × 2 = 4 |
| 3 | 12 | 1 1 1 0 | 12 | ไม่มี | 1 × 4 = 4 | 4 × 1 = 4 |
| 4 | 16 | 1 2 1 0 | 16 | ไม่มี | 0 × 12 = 0 | 12 × 1 = 12 |
รวมสองคอลัมน์สุดท้ายทุกแถวได้ 27 ตรงกับการไล่นับ 27 ชุด ตัวอย่างในโจทย์ใช้สูตรเดียวกันได้ 1 + 2 + 4 + 4 = 11 และ 11 หารเอาเศษด้วย 7 ได้ 4
ถ้าคำนวณก่อนหน้ากับช่วงกลางด้วยการคูณไล่ตรง ๆ ทุกแถว ก็คือวิธีที่ 3 ในตอนที่ 2
แต่ละแถวคูณไม่เกิน K ครั้ง รวมราว K² ได้ 70 คะแนน
ll own = m[i]; // m ของชนิดตัวเอง ในกล่องของตัวเอง
ll left = prod(0, i - 1); // ก่อนหน้า: ผลคูณของ (m + 1) ของชนิดที่มาก่อน
// กรณี (ข) ชนิดตัวเองไม่เต็มเพดาน ชนิดที่มาทีหลังต้องเป็นศูนย์ทั้งหมด
ans = (ans + own % MOD * left) % MOD;
// กรณี (ก) ชนิดตัวเองเต็มเพดาน ชนิดที่มาทีหลังใส่ได้จนกว่าจะถึงชนิด J ที่กลืน x ได้
int J = first_index_after_i_whose_rep_swallows(x);
ans = (ans + left * prod(i + 1, J - 1)) % MOD;
วิธีที่ 3 ช้าเพราะทุกแถวคูณก่อนหน้ากับช่วงกลางใหม่ตั้งแต่ต้น ระหว่างแถวมีแค่ค่า m + 1 ของไม่กี่ชนิดที่โตขึ้น
ของที่ต้องการคือโครงสร้างที่แก้ค่าช่องเดียวได้เร็ว และถามผลคูณของช่วงใดก็ได้เร็ว
ทุกทางที่ต้องหารใช้ไม่ได้ในข้อนี้ เหตุผลมีสองข้อ
M ไม่รับประกันว่าเป็นจำนวนเฉพาะ เลขที่มีตัวประกอบร่วมกับ M ไม่มีตัวผกผัน
(inverse คือเลขที่คูณแล้วได้ 1 เมื่อหารเอาเศษด้วย M)
M เป็นจำนวนเฉพาะ ค่า m + 1 ขึ้นได้ถึง 500,000 ซึ่งเกิน 30,000
อาจเป็นพหุคูณของ M พอหารเอาเศษแล้วกลายเป็น 0 ซึ่งหารไม่ได้
ต้นไม้เฟนวิก (Fenwick tree ตั้งชื่อตาม Peter Fenwick) เป็นตัวเลือกยอดนิยมสำหรับผลสะสมจากต้นถึงจุดหนึ่ง แต่ถ้าใช้เก็บผลคูณ มันต้องหารสองที่
ที่แรกคือตอนเอาช่วงกลาง ต้องหารผลคูณส่วนหน้าออก ที่สองคือตอนแก้ช่องจาก m + 1 เป็น m + 2
ต้องคูณทุกปมที่ครอบช่องนั้นด้วย (m + 2) / (m + 1) ต่อให้ถามแค่ผลคูณจากต้นก็ยังติดที่สอง
ต้นไม้ช่วงที่ทุกปมเก็บผลคูณของช่วงลูกทั้งสอง แก้ช่องได้ด้วยการคำนวณปมบนเส้นทางขึ้นไปใหม่ราว log K ปม
และถามช่วงใดก็ได้ด้วยการคูณชิ้นส่วนราว 2 log K ชิ้น ใช้แค่การคูณทั้งหมด
พื้นฐานของมันอยู่ในบท เซกเมนต์ทรีกับการค้นหาคำตอบแบบไบนารี
นับงานของเฉลยเต็มตามโค้ดจริง (ตัวเลขรวมอยู่ในตอนที่ 2)
F ครั้ง ครั้งละราว log K2 log K รวม 4K log K
โครงของโค้ดคือ เรียงปลาตามความยาว เรียงชนิดตามตัวแทน แล้วเดินตัวชี้ไปข้างหน้าอย่างเดียว
ทุกครั้งที่ปลาตัวหนึ่งเข้าเกณฑ์ ก็เพิ่ม m ของชนิดนั้นและแก้ช่องของมันในต้นไม้หนึ่งครั้ง
| ส่วนในโค้ด | ทำอะไร | ตอนที่ |
|---|---|---|
build / setv / prod | ต้นไม้ช่วงที่เก็บผลคูณ แก้ช่อง และถามผลคูณของช่วง | 5 |
เรียง ord ด้วย byType[t].back() | เรียงกล่องตามตัวแทนจากสั้นไปยาว | 3 |
ลูป while(ptr ...) | ปลาที่เพิ่งเข้าเกณฑ์ของแถวนี้ เพิ่ม m แล้วแก้ช่อง | 4 (ตัวเดินทีละชนิด) |
own, left, กรณี (ข) | m ของตัวเองคูณก่อนหน้า | 4 |
xi, need, J, กรณี (ก) | หา x กับ J แล้วคูณก่อนหน้ากับช่วงกลาง | 4 |
ตรวจอะไรไปแล้วบ้าง
brute.cpp ตรงกันทุกชุด
ครึ่งหนึ่งใช้ M เล็ก (2 ถึง 30) ให้การหารเอาเศษทำงานจริง
simulate.cpp เทียบกับ brute.cpp อีก 2,000 ชุด ตรงกันทุกชุดbrute.cpp และ simulate.cpp)
ได้ 4 และ 27 ตามลำดับ
ทั้งหมดนี้คือการตรวจตามขนาดที่สุ่ม ยังไม่ใช่บทพิสูจน์ว่าถูกทุกกรณี
| โปรแกรม | อินพุต | วินาที |
|---|---|---|
| เฉลยเต็ม | F = 500,000, K = 200,000 | 0.57 |
| เฉลยเต็ม | F = 500,000, K = 500,000 | 0.89 |
| วิธีที่ 3 (คูณไล่) | F = 500,000, K = 7,000 | 0.48 |
| วิธีที่ 2 (เพิ่มเข้าตัดออก) | F = 500,000, K = 20 | 0.36 |
เมื่อสิ่งที่นับเกิดได้จากหลายทาง ให้ตั้งกฎว่ามันเป็นของใครตั้งแต่แรก แล้วถามว่าเงื่อนไขไหนทำให้เจ้าของคนอื่นแย่งไปได้ ข้อนี้เหลือเงื่อนไขแค่ข้อ 3 กับข้อ 4 ของตอนที่ 4
ในหน้านี้