ผลต่างระหว่างรุ่นของ "Balkan2011"

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา
 
แถว 29: แถว 29:
 
'''เงื่อนไข'''
 
'''เงื่อนไข'''
  
- 1 <= N <= 100,000
+
1 <= N <= 100,000
  
- 1 <= ai, bi, ci, di <= 1,000,000,000
+
1 <= ai, bi, ci, di <= 1,000,000,000
  
- ถ้าตอบถูกเฉพาะจำนวนแรกในข้อมูลส่งออก จะได้คะแนน 40% ของข้อมูลทดสอบนั้นๆ
+
ถ้าตอบถูกเฉพาะจำนวนแรกในข้อมูลส่งออก จะได้คะแนน 40% ของข้อมูลทดสอบนั้นๆ
  
- 40% ของข้อมูลทดสอบทั้งหมดจะมี N <= 5,000
+
40% ของข้อมูลทดสอบทั้งหมดจะมี N <= 5,000
  
  
แถว 128: แถว 128:
  
 
3 4
 
3 4
 
  
  
แถว 138: แถว 137:
  
 
'''(หน่วยความจำ 64 MB,  เวลาทำงาน  2 sec,  คะแนนเต็ม 100 คะแนน)'''
 
'''(หน่วยความจำ 64 MB,  เวลาทำงาน  2 sec,  คะแนนเต็ม 100 คะแนน)'''
 +
 +
 +
คุณต้องการออกแบบอัลกอริทึมสำหรับเครื่องคอมพิวเตอร์รุ่นดึกดำบรรพ์ที่มีหน่วยความจำเพียง 10240 บิต เริ่มต้นหน่วยควมจำทั้งหมดมีค่าเป็น 0 และหลังจากนั้นคุณสามารถเขียนหรืออ่านได้ครั้งละหนึ่งบิต
 +
 +
 +
โดยคุณจะต้องเขียนสองการทำงานด้านล่างนี้ลงบนคอมพิวเตอร์:
 +
 +
remember(a): เมื่อ a แทนจำนวนเต็มมีค่าตั้งแต่ 0 ถึง 4095
 +
 +
การเขียนฟังก์ชันนี้สามารถเรียกใช้คำสั่ง:
 +
 +
bit_set(address): เมื่อ address แทนตัวเลขจำนวนเต็มตั้งแต่ 1 ถึง 10240
 +
 +
โดยที่หน่วยความจำหนึ่งบิตที่ตำแหน่ง address จะถูกเขียนค่าให้เป็น 1
 +
 +
 +
compare(b): เมื่อ b แทนจำนวนเต็มตั้งแต่ 0 ถึง 4095
 +
 +
ถ้า b < a, ให้คืนค่า -1
 +
 +
ถ้า b = a, ให้คืนค่า 0
 +
 +
ถ้า b > a, ให้คืนค่า 1
 +
 +
การเขียนฟังก์ชันนี้สามารถเรียกใช้คำสั่ง:
 +
 +
bit_get(address) ที่ทำหน้าที่คืนค่าหน่วยความจำหนึ่งบิตที่ตำแหน่ง address โดยจะมีค่าเป็น 1 ถ้าหน่วยความจำบิตนี้เคยถูกให้ค่าโดยคำสั่ง remember(a) มาก่อน, นอกจากนั้นจะมีค่ืนค่า 0
 +
 +
 +
'''งานของคุณ'''
 +
 +
ให้เขียนฟังกํชัน remember() และ compare() โดยเป้าหมายคือให้มีการเรียกใช้คำสั่งการเข้าถึงหน่วยความจำให้น้อยที่สุด (bit_set() และ bit_get()) ซึ่งคิดจากกรณีแย่สุดสำหรับทุกค่า a และ b ที่เป็นไปได้
 +
 +
 +
โปรแกรมของคุณจะมีการทำงานและเกณฑ์การให้คะแนนในรายละเอียดดังนี้ (ควรดาวน์โหลด code เพื่อดูประกอบครับ):
 +
 +
 +
กำหนดให้ AllMemory = array[0..4095][1..10240] เป็นอาร์เรย์สองมิติของบิต
 +
 +
ให้ค่าทุกช่องใน AllMemory เป็น 0
 +
 +
for a = 0..4095
 +
 +
remember(a)
 +
ซึ่งจะมีการกำหนด bit_set(address) (สำหรับ address บางค่าที่ต้องการ) และจะเปลี่ยนค่า AllMemory[a][address] ให้เป็น 1
 +
 
 +
 +
ให้ maxA คือ จำนวนครั้งที่มากที่สุดที่เรียกใช้คำสั่ง bit_set() สำหรับค่า a ใดๆ
 +
 +
for (a,b) in {0..4095}x{0..4095} ในลำดับสุ่ม (ทุกคู่ a,b จะถูกพิจารณา)
 +
 +
answer = compare(b)
 +
 +
ในคำสั่ง compare(b) จะมีการเรียกใช้คำสั่ง bit_get(address) ซึ่งจะคืนค่า AllMemory[a][address]
 +
 +
ถ้า answer ในการเปรียบเทียบค่า a และ b ไม่ถูกต้องจะได้คะแนนทั้งหมด 0 และจบโปรแกรม
 +
 +
ให้ maxB คือ จำนวนครั้งที่มากที่สุดที่เรียกใช้คำสั่ง bit_get() สำหรับคู่ a,b ใดๆ
 +
 +
T = maxA + maxB
 +
 +
ถ้า (T>20), คุณจะได้คะแนน 0 และจบโปรแกรม
 +
 +
นอกจากนั้น, คุณจะได้คะแนน 1+9*(21-T) และจบโปรแกรม
 +
 +
 +
 +
รายละเอียดเพิ่มเติมให้อ่านในโจทย์ต้นฉบับ
 +
คำแนะนำ: ให้อ่าน code ที่โจทย์แนบมาให้ครับ จะเข้าใจความสัมพันธ์ระหว่าง a และ b มากขึ้น เช่น ถ้าเขียนน้อยครั้ง ก็ อาจจะต้องอ่านหลายครั้ง เป็นต้น

รุ่นแก้ไขปัจจุบันเมื่อ 13:42, 3 กรกฎาคม 2557

BOI 2011 Day 2: Trapezoid

Source: http://www.boi2011.ro/resurse/tasks/trapezoid.pdf

(หน่วยความจำ 64 MB, เวลาทำงาน 0.5 sec, คะแนนเต็ม 100 คะแนน)

เมื่อพิจารณาเส้นตรงในแนวนอนสองเส้นใดๆ สี่เหลี่ยมคางหมู Ti สามารถสร้างขึ้นระหว่างเส้นทั้งสองนี้ โดยจะประกอบด้วยเส้นแนวตั้งที่เชื่อมจุดสองจุดบนเเส้นแนวนอนด้านบนและสองจุดจากเส้นด้านล่าง (ดูรูปประกอบ) เราจะตั้งชื่อจุดเหล่านี้ว่า ai, bi, ci, และ di ที่หมายถึงจุดบนซ้าย, บนขวา, ล่างซ้าย, และล่างขวา ตามลำดับ ซึ่งเป็นเป็นจุดยอดของสี่เหลี่ยมคางหมู Ti ซับเซต S ของสี่เหลี่ยมคางหมูจะเรียกว่าอิสระต่อกันเมื่อไม่มีสองสี่เหลี่ยมคางหมูใดใน S ที่ซ้อนทับกัน


หน้าที่ของคุณ

ให้หาว่าขนาด (cardinality) ของซับเซตของสี่เหลี่ยมคางหมูที่อิสระต่อกันที่ใหญ่ที่สุด (ขนาดใหญ่ที่สุดหมายถึงมีจำนวนสมาชิกมากที่สุด) และให้หาด้วยว่ามีซับเซตของสี่เหลี่ยมคางหมูที่อิสระต่อกันทั้งหมดกี่ซับเซตที่มีขนาดใหญ่ที่สุดเท่ากัน ให้ตอบจำนวนที่สองโดยใช้เศษจากการหาร (modulo) ด้วย 30013


ข้อมูลนำเข้า

บรรทัดที่ 1 ประกอบด้วย จำนวนเต็มหนึ่งจำนวน N ที่แสดงถึงจำนวนสี่เหลี่ยมคางหมูทั้งหมด ต่อมาอีก N บรรทัด แต่ละบรรทัดประกอบด้วยจำนวนเต็มสี่จำนวน ai, bi, ci, และ di ทั้งนี้ไม่มีสี่เหลี่ยมคางหมูใดๆ ที่มีจุดยอด (จุดมุม) เดียวกัน


ข้อมูลส่งออก

ให้แสดงคำตอบบรรทัดเดียวโดยประกอบไปด้วยจำนวนสองจำนวน คั่นด้วยช่องกลาง

จำนวนแรก คือ ขนาดของเซตของสี่เหลี่ยมคางหมูที่อิสระต่อกันที่ใหญ่ที่สุด

จำนวนที่สอง คือ จำนวนเซตที่อิสระต่อกัน ที่แตกต่างกันทั้งหมดที่เป็นไปได้ หารเอาเศษด้วย 30013


เงื่อนไข

1 <= N <= 100,000

1 <= ai, bi, ci, di <= 1,000,000,000

ถ้าตอบถูกเฉพาะจำนวนแรกในข้อมูลส่งออก จะได้คะแนน 40% ของข้อมูลทดสอบนั้นๆ

40% ของข้อมูลทดสอบทั้งหมดจะมี N <= 5,000


ตัวอย่าง

ควรดูรูปในโจทย์ประกอบครับ


BOI 2011 Day 2: TimeIsMoney

Source: http://www.boi2011.ro/resurse/tasks/timeismoney.pdf

(หน่วยความจำ 64 MB, เวลาทำงาน 2 sec, คะแนนเต็ม 100 คะแนน)

บริษัทเน็ตไลน์ต้องการติดตั้งเครือข่ายอินเทอร์เน็ตเพื่อเชือมโยง N เมืองเข้าด้วยกัน ในการนี้บริษัทจะต้อเชื่อมโยงเครือข่ายโดยใช้ลิงค์ทั้งหมด N-1 เส้นที่เชื่อมต่อระหว่างเมือสองเมือง ดังนั้นเมื่อเชื่อมต่อสำเร็จข้อความจะสามารถส่งผ่านจากเมืองหนึ่งไปยังเมืองอื่นๆทั้งหมดได้ ทั้งนี้บริษัทเน็ตไลน์ได้ระบุคู่ของเมืองทีั้งหมดที่สามารถจะสร้างลิงค์เชื่อมถึงกันได้ และในแต่ละลิงค์นั้นทางบริษัทได้คำนวณค่าใช้จ่ายและเวลาที่ต้องใช้ในการสร้างลิงค์เป็นที่เรีบบร้อยแล้วอีกด้วย

บริษัทสนใจที่จะหาค่าที่น้อยที่สุดของทั้งระยะเวลาในการสร้าง (สามารถสร้างได้เวลาละหนึ่งลิงค์) และจำนวนเงินที่ต้องใช้ในการสร้างลิงค์ทั้งหมดในเครือข่าย เนื่องจากพวกเขาไม่สามารถตัดสินใจที่จะเลือกระหว่างสองเงื่อนไขนี้พวกเขาจึงจะใช้สูตรในการคำนวนโดย:

SumTime = ผลรวมเวลาทั้งหมดที่ใช้ในการสร้างลิงค์ทั้งหมดที่เลือก

SumMoney = ผลรวมของจำนวนเงินทั้งหมดที่ต้องใช้ในการสร้างลิงค์ทั้งหมดที่เลือก

V = SumTime * SumMoney


งานของคุณ

ให้หารายการของ N-1 ลิงค์ที่จะสร้างและทำให้ค่า V ต่ำที่สุด


ข้อมูลนำเข้า

บรรทัดแรกประกอบด้วยจำนวนเต็มสองจำนวน: N แทยจำนวนเมืองและ M แทนจำนวนลิงค์ที่สามารถสร้างขึ้นโดยเชื่อมระหว่างเมืองสองเมืองเข้าด้วยกัน

ต่อมาอีก M บรรทัด แต่ละบรรทัดประกอบด้วยจำนวนเต็ม 4 จำนวน คือ x, y, t, และ c โดยหมายถึง เมือง x สามารถเชื่อมต่อไปยังเมือง y ได้ โดยใช้เวลาในการสร้าง t และค่าใช้จ่าย c


ข้อมูลส่งออก

บรรทัดแรกให้แสดงจำนวนสองจำนวน คือ เวลาทั้งหมด (SumTime) และจำนวนเงินทั้งหมด (SumMoney) ที่ใช้ในคำตอบที่ดีที่สุด (optimal solution ซึ่งเป็นคำตอบให้ค่า V น้อยที่สุด) โดยให้คั่นด้วยช่องว่างหนึ่งช่อง

ต่อมาอีก N-1 บรรทัด ให้แสดงลิงค์ที่จะสร้าง โดยในแต่ละบรรทัดให้ระบุตัวเลขสองจำนวนที่แสดงเมืองที่ต้องการเชื่อมต่อเข้าด้วยกัน (โดยลิงค์ที่ระบุจะต้องเป็นลิงค์ที่สามารถสร้างขึ้นได้) ตัวเลขแสดงคู่ของเมืองนี้สามารถแสดงในลำดับใดก็ได้

ถ้ามีคำตอบมากกว่าหนึ่งคำตอบ คุณสามารถตอบคำตอบใดก็ได้


เงื่อนไข

1 <= N <= 200

1 <= M <= 10,000

0 <= x,y <= N-1

1 <= t,c <= 255

มีหนึ่งชุดทดสอบที่ M = N-1

40% ของชุดทดสอบจะมีค่า t = c สำหรับทุกลิงค์ตั้งต้นที่กำหนดให้


ตัวอย่าง

input

5 7

0 1 161 79

0 2 161 15

0 3 13 153

1 4 142 183

2 4 236 80

3 4 40 241

2 1 65 92


output

279 501

2 1

0 3

0 2

3 4



BOI 2011 Day 2: Cmp

Source (โจทย์และไฟล์ที่จำเป็น): http://www.boi2011.ro/resurse/tasks/cmp.zip

(หน่วยความจำ 64 MB, เวลาทำงาน 2 sec, คะแนนเต็ม 100 คะแนน)


คุณต้องการออกแบบอัลกอริทึมสำหรับเครื่องคอมพิวเตอร์รุ่นดึกดำบรรพ์ที่มีหน่วยความจำเพียง 10240 บิต เริ่มต้นหน่วยควมจำทั้งหมดมีค่าเป็น 0 และหลังจากนั้นคุณสามารถเขียนหรืออ่านได้ครั้งละหนึ่งบิต


โดยคุณจะต้องเขียนสองการทำงานด้านล่างนี้ลงบนคอมพิวเตอร์:

remember(a): เมื่อ a แทนจำนวนเต็มมีค่าตั้งแต่ 0 ถึง 4095

การเขียนฟังก์ชันนี้สามารถเรียกใช้คำสั่ง:

bit_set(address): เมื่อ address แทนตัวเลขจำนวนเต็มตั้งแต่ 1 ถึง 10240

โดยที่หน่วยความจำหนึ่งบิตที่ตำแหน่ง address จะถูกเขียนค่าให้เป็น 1


compare(b): เมื่อ b แทนจำนวนเต็มตั้งแต่ 0 ถึง 4095

ถ้า b < a, ให้คืนค่า -1

ถ้า b = a, ให้คืนค่า 0

ถ้า b > a, ให้คืนค่า 1

การเขียนฟังก์ชันนี้สามารถเรียกใช้คำสั่ง:

bit_get(address) ที่ทำหน้าที่คืนค่าหน่วยความจำหนึ่งบิตที่ตำแหน่ง address โดยจะมีค่าเป็น 1 ถ้าหน่วยความจำบิตนี้เคยถูกให้ค่าโดยคำสั่ง remember(a) มาก่อน, นอกจากนั้นจะมีค่ืนค่า 0


งานของคุณ

ให้เขียนฟังกํชัน remember() และ compare() โดยเป้าหมายคือให้มีการเรียกใช้คำสั่งการเข้าถึงหน่วยความจำให้น้อยที่สุด (bit_set() และ bit_get()) ซึ่งคิดจากกรณีแย่สุดสำหรับทุกค่า a และ b ที่เป็นไปได้


โปรแกรมของคุณจะมีการทำงานและเกณฑ์การให้คะแนนในรายละเอียดดังนี้ (ควรดาวน์โหลด code เพื่อดูประกอบครับ):


กำหนดให้ AllMemory = array[0..4095][1..10240] เป็นอาร์เรย์สองมิติของบิต

ให้ค่าทุกช่องใน AllMemory เป็น 0

for a = 0..4095

remember(a) ซึ่งจะมีการกำหนด bit_set(address) (สำหรับ address บางค่าที่ต้องการ) และจะเปลี่ยนค่า AllMemory[a][address] ให้เป็น 1


ให้ maxA คือ จำนวนครั้งที่มากที่สุดที่เรียกใช้คำสั่ง bit_set() สำหรับค่า a ใดๆ

for (a,b) in {0..4095}x{0..4095} ในลำดับสุ่ม (ทุกคู่ a,b จะถูกพิจารณา)

answer = compare(b)

ในคำสั่ง compare(b) จะมีการเรียกใช้คำสั่ง bit_get(address) ซึ่งจะคืนค่า AllMemory[a][address]

ถ้า answer ในการเปรียบเทียบค่า a และ b ไม่ถูกต้องจะได้คะแนนทั้งหมด 0 และจบโปรแกรม

ให้ maxB คือ จำนวนครั้งที่มากที่สุดที่เรียกใช้คำสั่ง bit_get() สำหรับคู่ a,b ใดๆ

T = maxA + maxB

ถ้า (T>20), คุณจะได้คะแนน 0 และจบโปรแกรม

นอกจากนั้น, คุณจะได้คะแนน 1+9*(21-T) และจบโปรแกรม


รายละเอียดเพิ่มเติมให้อ่านในโจทย์ต้นฉบับ คำแนะนำ: ให้อ่าน code ที่โจทย์แนบมาให้ครับ จะเข้าใจความสัมพันธ์ระหว่าง a และ b มากขึ้น เช่น ถ้าเขียนน้อยครั้ง ก็ อาจจะต้องอ่านหลายครั้ง เป็นต้น