วงกลมแบ่งระนาบ


23

งาน

คุณจะได้รับชุดของวงการในระนาบกับศูนย์ของพวกเขาในสายการ y = 0 รับประกันว่าจะไม่มีวงกลมคู่ใดมีจุดร่วมมากกว่าหนึ่งจุด

งานของคุณคือกำหนดจำนวนภูมิภาคที่วงกลมแบ่งเครื่องบิน ภูมิภาคคือชุดของจุดที่ต่อเนื่องกันที่รวมเข้าด้วยกันอย่างสูงสุดซึ่งไม่ได้ตัดกันวงกลมใด ๆ

คุณควรเขียนโปรแกรมที่คำนวณคำตอบนี้เมื่อได้รับคำอธิบายของแวดวง


นี่คือตัวอย่าง:

ตัวอย่างที่ 1

ทางด้านซ้ายคุณจะเห็นวงกลมที่วาดในระนาบ อย่างไรก็ตามในครึ่งด้านขวาของภาพภูมิภาคที่ผลิตโดยวงกลมจะมีสีชัดเจน (หนึ่งสีต่อภูมิภาค) ในตัวอย่างนี้มีหกภูมิภาค


อินพุต

บรรทัดแรกของอินพุตมีจำนวน, Nจำนวนของคำอธิบายวงกลมที่ต้องติดตาม บรรทัดนี้เป็นทางเลือกถ้าโซลูชันของคุณใช้งานไม่ได้ก็ไม่เป็นไร

ต่อไปนี้Nแต่ละบรรทัดมีสองจำนวนเต็มx ฉันและr ฉัน > 0คิดเป็นวงกลมที่มีศูนย์(x ฉัน , 0)และรัศมีRฉัน

รับประกันว่าจะไม่มีวงกลมคู่ใดมีจุดร่วมมากกว่าหนึ่งจุด มีการรับประกันเพิ่มเติมว่าx iและr iไม่เกิน10^9ค่าสัมบูรณ์ (ดังนั้นพวกเขาจึงพอดีกับจำนวนเต็ม 32 บิต)


อินพุตอาจเป็น:

  • อ่านจาก STDIN

  • อ่านจากไฟล์ชื่อIในไดเรกทอรีปัจจุบัน

อีกทางหนึ่งอินพุตอาจเป็น:

  • เป็นสตริง (รวมถึงการขึ้นบรรทัดใหม่) ในตัวแปรทั่วโลก

  • บนสแต็ก


เอาท์พุต

นี่ควรเป็นเลขจำนวนเต็มเดียวคือตัวเลขตามภูมิภาคที่ผลิต สิ่งนี้ควรถูกเขียนไปยัง STDOUT หรือไฟล์ที่มีชื่อOในไดเรกทอรีปัจจุบัน


กฎระเบียบ

  • รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ

  • การลงโทษ +200 ไบต์ถ้ารหัสของคุณไม่มีพหุนาม + ความซับซ้อนของพื้นที่ว่าง n

  • -100 โบนัสไบต์สำหรับกรณีรันไทม์ + ความซับซ้อนของพื้นที่ว่างที่คาดว่าเลวร้ายที่สุด O(n log n)

  • โบนัส -50 ไบต์สำหรับกรณีรันไทม์ + ความซับซ้อนของพื้นที่ว่างที่คาดว่าเลวร้ายที่สุด O(n)

  • โบนัส -100 ไบต์สำหรับการกำหนดรันไทม์ + ความซับซ้อนของพื้นที่ว่าง O(n)

ขณะประเมินรันไทม์:

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

  • สมมติว่าการเรียงลำดับภาษาในโปรแกรมของคุณใช้เวลาที่กำหนดO(n log n)ซึ่งnขนาดของลำดับการป้อนข้อมูล

  • สมมติว่าดำเนินการทางคณิตศาสตร์ในการป้อนข้อมูลตัวเลขที่ใช้เวลาเพียงO(1)เวลา

  • อย่าสันนิษฐานว่าตัวเลขอินพุตนั้นถูกโยงด้วยค่าคงที่แม้ว่าด้วยเหตุผลเชิงปฏิบัติ ซึ่งหมายความว่าอัลกอริทึมเช่นการเรียงลำดับ Radix หรือการเรียงลำดับการนับไม่ใช่เวลาเชิงเส้น โดยทั่วไปควรหลีกเลี่ยงปัจจัยคงที่ที่มีขนาดใหญ่มาก


ตัวอย่าง

การป้อนข้อมูล:

2 
1 3
5 1

เอาท์พุท: 3


การป้อนข้อมูล:

3
2 2
1 1
3 1

เอาท์พุท: 5

4
7 5
-9 11
11 9
0 20

การป้อนข้อมูล:

9
38 14
-60 40
73 19
0 100
98 2
-15 5
39 15
-38 62
94 2

เอาท์พุท: 11


คำแนะนำ

เราสามารถใช้แนวคิดต่อไปนี้สำหรับโซลูชันที่กะทัดรัดมาก ให้ตัดชุดวงกลมด้วยแกน X และตีความจุดตัดกันเป็นโหนดในกราฟระนาบ:

ป้อนคำอธิบายรูปภาพที่นี่

วงกลมทุกวงสร้าง 2 ขอบที่แน่นอนในกราฟนี้และมากถึงสองโหนด เราสามารถนับจำนวนโหนดโดยใช้ตารางแฮชเพื่อติดตามจำนวนรวมของเส้นขอบซ้ายหรือขวาที่แตกต่างกัน

จากนั้นเราสามารถใช้สูตรลักษณะออยเลอร์เพื่อคำนวณจำนวนใบหน้าของการวาดภาพของกราฟ:

V - E + F - C = 1

F = E - V + C + 1

เพื่อคำนวณCจำนวนขององค์ประกอบที่เกี่ยวโยงกันที่เราสามารถใช้การค้นหาความลึกแรก


หมายเหตุ: แนวคิดนี้เป็นปัญหาที่ยืมมาจากการประกวดการเขียนโปรแกรมภาษาโครเอเชียเมื่อเร็ว ๆ นี้แต่โปรดอย่าโกงโดยดูที่หัวข้อการแก้ปัญหา :)


โบนัสเหล่านี้บางตัวล่อหรือไม่
user2357112 รองรับ Monica

@ user2357112 อย่าคิดว่ามันไม่สามารถทำได้เว้นแต่คุณจะพิสูจน์ได้)
Niklas B.

ด้วยอินพุตที่รับประกันว่าจะพอดีกับจำนวนเต็มของเครื่องเราสามารถใช้การเรียงลำดับแบบ Radix และเรียกมันว่า O (n) ฉันเกลียดการสมมติขนาดอินพุตที่ จำกัด เนื่องจากการพูดอย่างเคร่งครัดหมายความว่ามีอินพุตที่เป็นไปได้จำนวน จำกัด
user2357112 รองรับ Monica

@ user2357112 ไม่ฉันบอกว่าคุณไม่สามารถสรุปได้ว่าจำนวนเต็มจะถูก จำกัด ขอบเขตในขณะที่ประเมิน asymptotics ดังนั้นการเรียงลำดับ radix หรือการนับจะไม่ใช่เชิงเส้นเวลาและพื้นที่ ว่าพวกเขาพอดีเป็นคำเพียงเพื่อทำ arithmetics "จริง" O (1) และสำหรับเหตุผลในทางปฏิบัติ (ความกว้างตัวแปรล้อมรอบในภาษาส่วนใหญ่)
Niklas B.

@NiklasB ถ้าฉันมีอัลกอริธึมที่มีองค์ประกอบเดียวที่มีความซับซ้อนแบบ superlinear คือการเรียงลำดับฉันต้องใช้การเรียงแบบผสานถ้าภาษาของฉันใช้การเรียงแบบด่วนเพื่อรับn log nโบนัสหรือไม่ นอกจากนี้ฉันมีวิธีแก้ไขปัญหาแนวคิดใหม่ ฉันควรโพสต์คำตอบใหม่เพื่อแทนที่คำตอบเดิมหรือไม่? (ฉันชอบแบบเก่าในกรณีที่โซลูชันใหม่ของฉันไม่ถูกต้องจริง ๆ )
Martin Ender

คำตอบ:


2

Mathematica, 125 122 - 150 = -28 ตัวอักษร

ฉันไม่รู้ความซับซ้อนของฟังก์ชั่นในConnectedComponentsตัว

1+{-1,2,1}.Length/@{VertexList@#,EdgeList@#,ConnectedComponents@#}&@Graph[(+##)<->(#-#2)&@@@Rest@ImportString[#,"Table"]]&

การใช้งาน:

1+{-1,2,1}.Length/@{VertexList@#,EdgeList@#,ConnectedComponents@#}&@Graph[(+##)<->(#-#2)&@@@Rest@ImportString[#,"Table"]]&[
"9
38 14
-60 40
73 19
0 100
98 2
-15 5
39 15
-38 62
94 2"]

11


ฉันคิดว่าเราสามารถคาดเดาได้อย่างปลอดภัยว่าConnectedComponentsมีความซับซ้อนของเส้นตรงที่เลวร้ายที่สุดดังนั้นหากมีองค์ประกอบ O (n) สิ่งนี้จะใช้ได้ ฉันไม่เข้าใจ Mathematica ดังนั้นฉันจึงไม่สามารถบอกได้ว่ามันเป็น O (n) โดยรวมและมีคุณสมบัติสำหรับ -150 โบนัสหรือไม่ ฉันคิดว่ามันทำ ฉันเพิ่งรันด้วยอินพุตใน STDIN หรือไม่
Niklas B.

@NiklasB วิธีการป้อนข้อมูลของเขาเป็นเพียงการส่งตัวแปรสตริงไปยังฟังก์ชั่นที่ไม่ระบุชื่อ ดังนั้นฉันคิดว่าควรมีคุณสมบัติ สำหรับผลลัพธ์ใน Mathematica สิ่งนี้จะส่งผลให้จำนวนสิ้นสุดลงในผลลัพธ์ของคอนโซลดังนั้นมันก็น่าจะดีเช่นกัน
Martin Ender

ฉันตรวจสอบความถูกต้องของสิ่งนี้แล้วดังนั้นฉันจึงคิดว่ามีคะแนน -28 นี่คือผู้นำคนใหม่ ขอแสดงความยินดี!
Niklas B.

@NiklasB ทำไมแค่ 150 ส่วนใดของอัลกอริทึมที่มีความซับซ้อนของกรณีที่แย่ที่สุด
Martin Ender

@ m.buettner 150 สำหรับเวลา O (n) ที่คาดไว้ สำหรับกราฟที่มีตัวเลขโดยพลการเป็นโหนดซึ่งกำหนดไว้ที่นี่โดยปริยายคุณจะไม่สามารถหาจำนวน CCs ในเวลาเชิงเส้นซึ่งสามารถแสดงได้โดยการลดความแตกต่างขององค์ประกอบให้กับองค์ประกอบที่เชื่อมต่อ ฉันคิดว่าเราสามารถลดความแตกต่างขององค์ประกอบให้กับปัญหาดั้งเดิมได้
Niklas B.

4

Ruby - 312 306 285 273 269 259 ตัวอักษร

คำตอบนี้ถูกแทนที่ด้วยวิธีการอื่นของฉันซึ่งใช้อักขระน้อยลงและวิ่งเข้ามาO(n log n)มาก

เอาล่ะไปกันเถอะ สำหรับผู้เริ่มต้นฉันแค่ต้องการนำไปใช้งานจริงดังนั้นนี่ยังไม่ได้ปรับขั้นตอนวิธี ฉันเรียงลำดับวงกลมจากใหญ่ที่สุดไปหาเล็กที่สุดและสร้างต้นไม้ (วงกลมที่รวมอยู่ในแวดวงอื่น ๆ เป็นลูกของวงกลมใหญ่เหล่านั้น) การดำเนินการทั้งสองดำเนินO(n^2)ไปอย่างแย่ที่สุดและO(n log n)ดีที่สุด จากนั้นฉันย้ำผ่านต้นไม้เพื่อนับพื้นที่ หากลูกของวงกลมเติมเต็มเส้นผ่านศูนย์กลางทั้งหมดจะมีสองพื้นที่ใหม่มิฉะนั้นจะมีเพียงหนึ่งพื้นที่ O(n)ย้ำใช้เวลานี้ ดังนั้นฉันจึงมีความซับซ้อนโดยรวมO(n^2)และมีคุณสมบัติไม่ให้รางวัลและการลงโทษ

รหัสนี้คาดว่าอินพุตที่ไม่มีจำนวนของแวดวงจะถูกเก็บไว้ในตัวแปรs:

t=[]
s.lines.map{|x|x,r=x.split.map &:to_i;{d:2*r,l:x-r,c:[]}}.sort_by!{|c|-c[:d]}.map{|c|i=-1;n=t
while o=n[i+=1]
if 0>d=c[:l]-o[:l]
break
elsif o[:d]>d
n=o[:c]
i=-1
end
end
n[i,0]=c}
a=1
t.map &(b=->n{d=0
n[:c].each{|c|d+=c[:d]}.map &b
a+=d==n[:d]?2:1})
p a

เวอร์ชันที่ไม่ถูกปรับแต่ง (คาดว่าอินพุตในตัวแปรstring):

list = []
string.split("\n").map { |x|
  m = x.split
  x,radius = m.map &:to_i
  list<<{x:x, d:2*radius, l:x-radius, r:x+radius, children:[]}
}
list.sort_by! { |circle| -circle[:d] }
tree = []
list.map { |circle|
  i = -1
  node = tree
  while c=node[i+=1]
    if circle[:x]<c[:l]
      break
    elsif circle[:x]<c[:r]
      node = c[:children]
      i = -1
    end
  end
  node[i,0] = circle
}
areas = 1
tree.map &(count = -> node {
  d = 0
  i = -1
  while c=node[:children][i+=1]
    count.call c
    d += c[:d]
  end
  areas += d == node[:d] ? 2 : 1
})
p areas

@NiklasB ใช่ว่ากรณีทดสอบจะดี ความสัมพันธ์ที่กำหนดขอบในต้นไม้ของฉันคือการรวมวงกลมหนึ่งวงเข้าด้วยกัน เนื่องจากบนแวดวงไม่สามารถมีอยู่ในวงกลมสองวงที่ไม่มีกันและกัน (เนื่องจากเงื่อนไข "หนึ่งจุดตัด") ฉันไม่เห็นว่านี่จะเป็น DAG ได้อย่างไร
Martin Ender

ลูกหลานของโหนดยังเป็นลูกของมันด้วยหรือไม่
user2357112 รองรับ Monica

@ user2357112 ไม่เพราะพวกเขาสามารถแยกผู้ปกครองโดยตรงเท่านั้น
Martin Ender

@NiklasB 11ถ้าผมเรียกมันด้วยตัวอย่างเช่นในคำถามของคุณที่ผมได้รับ 9สำหรับหนึ่งในความคิดเห็นของคุณ
Martin Ender

@NiklasB รอฉันจริง10และได้รับ8กับรุ่น ungolfed ของฉัน แต่11และ9กับรุ่น golfed ปัจจุบันของฉัน: D
Martin Ender

2

Ruby, 203 183 173 133 - 100 = 33 ตัวอักษร

ดังนั้นนี่คือแนวทางที่แตกต่าง ครั้งนี้ฉันจัดเรียงวงกลมตามจุดซ้ายสุดของพวกเขา วงกลมที่สัมผัสที่จุดซ้ายสุดจะถูกจัดเรียงจากใหญ่ไปหาน้อยที่สุด สิ่งนี้ใช้เวลาO(n log n)(ดี, Ruby ใช้การเรียงลำดับด่วน, จริง ๆ แล้ว, O(n^2)แต่การใช้การเรียงลำดับผสาน / กองอาจจะเกินขอบเขตของความท้าทายนี้). จากนั้นฉันทำซ้ำในรายการนี้โดยจดจำตำแหน่งซ้ายสุดและขวาสุดของแวดวงที่ฉันได้เยี่ยมชม สิ่งนี้ทำให้ฉันสามารถตรวจสอบได้ว่ามีชุดของวงกลมเชื่อมต่อกันตลอดทางผ่านวงกลมที่ใหญ่กว่าหรือไม่ ในกรณีนี้มีพื้นที่ย่อยสองชุดไม่อย่างนั้นจะเป็นพื้นที่ย่อย การวนซ้ำนี้ใช้เวลาเพียงO(n)ให้ความซับซ้อนโดยรวมO(n log n)ซึ่งมีคุณสมบัติสำหรับรางวัล 100 ตัวอักษร

ตัวอย่างนี้คาดว่าอินพุตจะถูกส่งผ่านไฟล์ในอาร์กิวเมนต์บรรทัดคำสั่งโดยไม่ต้องมีแวดวง:

l,r={},{}
a=1
$<.map{|x|c,q=x.split.map &:to_r;[c-q,-2*q]}.sort.map{|x,y|a+=r[y=x-y]&&l[x]?2:1
l[y]=1 if l[x]&&!r[y]
l[x]=r[y]=1}
p a

เวอร์ชันที่ไม่ถูกปรับแต่ง (คาดว่าอินพุตในตัวแปรstring):

list = []
string.split("\n").map { |x|
  m = x.split
  x,radius = m.map &:to_r
  list<<{x:x, d:2*radius, l:x-radius, r:x+radius}
}
list.sort_by! { |circle| circle[:l] + 1/circle[:d] }
l,r={},{}
areas = 1
list.map { |circle|
  x,y=circle[:l],circle[:r]
  if l[x] && r[y]
    areas += 2
  else
    areas += 1
    l[y]=1 if l[x]
  end
  r[y]=1
  l[x]=1
}
p areas

น่าเสียดายที่สิ่งนี้ล้มเหลวสำหรับ testcase ที่ใหญ่กว่าทั้งหมด มันเร็ว แต่;) ฉันไม่มีตัวอย่างความล้มเหลวเล็กน้อยในครั้งนี้ แต่คุณสามารถค้นหาข้อมูลการทดสอบบนเว็บไซต์การประกวดที่ฉันเชื่อมโยงกับ (มันคือการประกวด # 6)
Niklas B.

testcase ที่ล้มเหลวครั้งแรกคือ kruznice / kruznice.in.2 ซึ่งเป็นกรณีทดสอบ "ของจริง" ครั้งแรกดังนั้นฉันคิดว่ามีบางสิ่งผิดปกติในขั้นตอนวิธีหรือการใช้งาน มันทำงานถูกต้องกับวงกลมซ้อนกันโดยพลการหรือไม่?
Niklas B.

@NiklasB ขอบคุณฉันจะต้องดูเป็นกรณีทดสอบที่ (อาจจะใช้เวลาฉันจนกระทั่งคืนวันพรุ่งนี้ที่จะแก้ไขได้แม้ว่า)
มาร์ตินเอนเดอร์

@NiklasB ฉันคิดว่าปัญหาและความล้มเหลวในตัวอย่างขั้นต่ำต้อง 5 -1 1 1 1 0 2 4 2 0 6วงการ: ฉันจะคิดถึงวิธีแก้ไขปัญหานี้ในคืนพรุ่งนี้ (หวังว่า)
Martin Ender

การวิเคราะห์ความซับซ้อนของคุณดูเหมือนว่าสมมติว่าการเข้าถึงอาเรย์แบบเชื่อมโยงเป็นเวลาคงที่ ดูเหมือนว่าไม่น่าจะเป็นจริงในกรณีที่เลวร้ายที่สุด
Peter Taylor

1

Julia - 260 -100 (โบนัส?) = 160

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

UPDATE:โดยการคิดว่าฉันคิดว่าปัญหาของวิธีการของฉันนั้นเป็นเพียงเมื่อวงกลมที่ไม่ได้เชื่อมต่อดังนั้นฉันจึงมีความคิดทำไมไม่เชื่อมต่อพวกเขาด้วยความผิด ดังนั้นทั้งหมดจะเป็นไปตามสูตรของออยเลอร์

ตัวอย่างของแวดวง

F = 2 + EV (V = 6, E = 9)

[อย่าทำงานกับวงกลมที่ซ้อนกันดังนั้นจึงไม่ใช่คำตอบของปัญหาสำหรับกรณีทั่วไป]

รหัส :

s=readlines(open("s"))
n=int(s[1])
c=zeros(n,2)
t=[]
for i=1:n
    a=int(split(s[i+1]))
    c[i,1]=a[1]-a[2]
    c[i,2]=a[1]+a[2]
    if i==1 t=[c[1]]end
    append!(t,[c[i,1]:.5:c[i,2]])
end
e=0
t=sort(t)
for i in 1:(length(t)-1) e+=t[i+1]-t[i]>=1?1:0end #adds one edge for every gap
2+2n+e-length(unique(c)) # 2+E-V = 2+(2n+e)-#vertices

2 -10 1 10 1ผมคิดว่าโปรแกรมของคุณจะล้มเหลว
Niklas B.

"รับประกันได้ว่าไม่มีวงกลมคู่ใดมีจุดร่วมมากกว่าหนึ่งจุด" ดังนั้นฉันคิดว่ามันจะไม่มีผล :)
CCP

@CCP พวกเขามีศูนย์คะแนนร่วมกัน n=2วงกลมอยู่(C=(-10,0), r=1)และ(C=(10,0), r=1)
Niklas B.

1
กราฟไม่จำเป็นต้องเชื่อมต่อเพื่อใช้คุณสมบัติออยเลอร์หรือไม่?
user2357112 รองรับ Monica

1
อานี่เป็นกรณีง่าย ๆ : 4 0 2 1 1 10 2 11 1แต่ฉันไม่คิดว่าฉันจะให้กรณีทดสอบเพิ่มเติมอีกมากมายซึ่งอาจไม่ยุติธรรมสักหน่อย
Niklas B.

1

Spidermonkey JS, 308, 287 , 273 - 100 = 173

ฉันคิดว่าถ้าฉันเขียนใหม่ใน Ruby หรือ Python ฉันสามารถบันทึกตัวละคร

รหัส:

for(a=[d=readline],e={},u=d(n=1);u--;)[r,q]=d().split(' '),l=r-q,r-=-q,e[l]=e[l]||[0,0],e[r]=e[r]||[0,0],e[r][1]++,e[l][0]++
for(k=Object.keys(e).sort(function(a,b)b-a);i=k.pop();a.length&&a.pop()&a.push(0)){for([l,r]=e[i];r--;)n+=a.pop()
for(n+=l;l--;)a.push(l>0)}print(n)

ขั้นตอนวิธีการ:

n = 1 // this will be the total
e = {x:[numLeftBounds,numRightBounds]} // imagine this as the x axis with a count of zero-crossings
a = [] // this is the stack of circles around the "cursor".  
       // values will be 1 if that circle's never had alone time, else 0
k = sort keys of e on x
for each key in k: // this is the "cursor"
  n += key[numLeftBounds] // each circle that opens has at least one space.
  k[numRightBounds].times {n += a.pop()} // pop the closing circles. if any were never alone, add 1
  k[numLeftBounds].times {a.push(alwaysAlone)} // push the opening circles
  if !a.empty():
     set the innermost circle (top of stack) to false (not never alone)
  fi
loop

ฉันไม่เก่งอย่างยิ่งกับสัญกรณ์ O ใหญ่ แต่ฉันคิดว่านั่นคือ O (n) เนื่องจากฉันวนลูปได้อย่างมีประสิทธิภาพในแต่ละวงกลม 3 ครั้ง (สร้างซ้ายซ้ายขวา) และเรียงลำดับคีย์ของแผนที่ (และฉันเรียงลำดับสำหรับ O ( n บันทึก n) แต่นั่นหายไป) เป็นสิ่งกำหนดหรือไม่?


หากใครมีคำแนะนำใด ๆ ในการรวมrลูปและlลูปเข้าในคำสั่งเดียวฉันจะขอบคุณมัน
ไม่ใช่ Charles

ไชโย :) ดูเหมือนว่าฉันของคุณรันไทม์เป็น O (n log n) เนื่องจากการเรียงลำดับซึ่งจะเป็น -100 ฉันจะแจ้งให้คุณทราบว่าผ่านการทดสอบทุกกรณีหรือไม่
Niklas B.

ดีมากโปรแกรมของคุณผ่านการทดสอบทั้งหมดในการลองครั้งแรก ฉันคิดว่าสิ่งนี้ (sweepline กับบางรัฐไว้ในกอง) เป็นทางออกอย่างเป็นทางการจากผู้เขียนปัญหา โปรแกรมของคุณได้รับคะแนนรวม 173
Niklas B.

@NiklasB ขอบคุณ!
ไม่ใช่ Charles

ฉันพยายามแก้ปัญหาที่มีประสิทธิภาพมากขึ้นด้วยวงกลมที่ทับซ้อนกัน .... จากนั้นฉันเห็นว่าพวกเขาสามารถตัดกันได้เพียงจุดเดียว
ไม่ใช่ว่า Charles

-1

JavaScript (ES6) - 255 254 ตัวอักษร - 100 250 โบนัส = 155 4

R=/(\S+) (\S+)/ym;N=1;i=w=l=0;for(X=[];m=R.exec(S);){X[N++]={w:j=m[2]*1,l:k=m[1]-j,r:k+2*j};l=k<l?k:l;w=j<w?w:j}M=[];X.map(x=>M[(x.l-l+1)*w-x.w]=x);s=[];M.map(x=>{while(i&&s[i-1].r<x.r)N+=s[--i].w?0:1;i&&(s[i-1].w-=x.w);s[i++]=x});while(i)N+=s[--i].w?0:1

สมมติว่าสตริงอินพุตอยู่ในตัวแปรSและส่งออกจำนวนของขอบเขตไปยังคอนโซล

R=/(\S+) (\S+)/ym;                  // Regular expression to find centre and width.
N=1;                                // Number of regions
w=l=0;                              // Maximum width and minimum left boundary.
X=[];                               // A 1-indexed array to contain the circles.
                                    // All the above are O(1)
for(;m=R.exec(S);){                 // For each circle
    X[N++]={w:j=m[2]*1,l:k=m[1]-j,r:k+2*j};
                                    // Create an object with w (width), l (left boundary)
                                    // and r (right boundary) attributes.
    l=k<l?k:l;                      // Update the minimum left boundary.
    w=j<w?w:j                       // Update the maximum width.
}                                   // O(1) per iteration = O(N) total.
M=[];                               // An array.
X.map(x=>M[(x.l-l+1)*w-x.w]=x);     // Map the 1-indexed array of circles (X) to a
                                    // sparse array indexed so that the elements are
                                    // sorted by ascending left boundary then descending
                                    // width.
                                    // If there are N circles then only N elements are
                                    // created in the array and it can be treated as if it
                                    // is a hashmap (associative array) with a built in
                                    // ordering and as per the rules set in the question
                                    // is O(1) per insert so is O(N) total cost.
                                    // Since the array is sparse then it is still O(N)
                                    // total memory.
s=[];                               // An empty stack
i=0;                                // The number of circles on the stack.
M.map(x=>{                          // Loop through each circle
    while(i&&s[i-1][1]<x[1])        // Check to see if the current circle  is to the right
                                    // of the circles on the stack;
      N+=s[--i][0]?0:1;             // if so, decrement the length of the stack and if the
                                    // circle that pops off has radius equal to the total
                                    // radii of its children then increment the number of
                                    // regions by 1.

                                    // Since there can be at most N items on the stack then
                                    // there can be at most N items popped off the stack
                                    // over all the iterations; therefore this operation
                                    // has an O(N) total cost.
    i&&(s[i-1][0]-=x[0]);           // If there is a circle on the stack then this circle
                                    // is its child. Decrement the parent's radius by the
                                    // current child's radius.
                                    // O(1) per iteration
    s[i++]=x                        // Add the current circle to the stack.
  });
while(i)N+=s[--i][0]?0:1            // Finally, remove all the remaining circles from the
                                    // stack and if the circle that pops off has radius
                                    // equal to the total radii of its children then
                                    // increment the number of regions by 1.
                                    // Since there will always be at least one circle on the
                                    // stack then this has the added bonus of being the final
                                    // command so the value of N is printed to the console.
                                    // As per the previous comment on the complexity, there
                                    // can be at most N items on the stack so between this
                                    // and the iterations over the circles then there can only
                                    // be N items popped off the stack so the complexity of
                                    // all these tests on the circles on the stack is O(N).

ความซับซ้อนของเวลาในขณะนี้คือ O (N)

กรณีทดสอบ 1

S='2\n1 3\n5 1';
R=/(\S+) (\S+)/ym;N=1;i=w=l=0;for(X=[];m=R.exec(S);){X[N++]={w:j=m[2]*1,l:k=m[1]-j,r:k+2*j};l=k<l?k:l;w=j<w?w:j}M=[];X.map(x=>M[(x.l-l+1)*w-x.w]=x);s=[];M.map(x=>{while(i&&s[i-1].r<x.r)N+=s[--i].w?0:1;i&&(s[i-1].w-=x.w);s[i++]=x});while(i)N+=s[--i].w?0:1

ขาออก: 3

กรณีทดสอบ 2

S='3\n2 2\n1 1\n3 1';
R=/(\S+) (\S+)/ym;N=1;i=w=l=0;for(X=[];m=R.exec(S);){X[N++]={w:j=m[2]*1,l:k=m[1]-j,r:k+2*j};l=k<l?k:l;w=j<w?w:j}M=[];X.map(x=>M[(x.l-l+1)*w-x.w]=x);s=[];M.map(x=>{while(i&&s[i-1].r<x.r)N+=s[--i].w?0:1;i&&(s[i-1].w-=x.w);s[i++]=x});while(i)N+=s[--i].w?0:1

ขาออก: 5

กรณีทดสอบ 3

S='4\n7 5\n-9 11\n11 9\n0 20';
R=/(\S+) (\S+)/ym;N=1;i=w=l=0;for(X=[];m=R.exec(S);){X[N++]={w:j=m[2]*1,l:k=m[1]-j,r:k+2*j};l=k<l?k:l;w=j<w?w:j}M=[];X.map(x=>M[(x.l-l+1)*w-x.w]=x);s=[];M.map(x=>{while(i&&s[i-1].r<x.r)N+=s[--i].w?0:1;i&&(s[i-1].w-=x.w);s[i++]=x});while(i)N+=s[--i].w?0:1

ขาออก: 6

กรณีทดสอบ 4

S='9\n38 14\n-60 40\n73 19\n0 100\n98 2\n-15 5\n39 15\n-38 62\n94 2';
R=/(\S+) (\S+)/ym;N=1;i=w=l=0;for(X=[];m=R.exec(S);){X[N++]={w:j=m[2]*1,l:k=m[1]-j,r:k+2*j};l=k<l?k:l;w=j<w?w:j}M=[];X.map(x=>M[(x.l-l+1)*w-x.w]=x);s=[];M.map(x=>{while(i&&s[i-1].r<x.r)N+=s[--i].w?0:1;i&&(s[i-1].w-=x.w);s[i++]=x});while(i)N+=s[--i].w?0:1

ขาออก: 11

กรณีทดสอบ 5

S='87\n-730 4\n-836 2\n-889 1\n-913 15\n-883 5\n-908 8\n-507 77\n-922 2\n-786 2\n-782 2\n-762 22\n-776 2\n-781 3\n-913 3\n-830 2\n-756 4\n-970 30\n-755 5\n-494 506\n-854 4\n15 3\n-914 2\n-840 2\n-833 1\n-505 75\n-888 10\n-856 2\n-503 73\n-745 3\n-903 25\n-897 1\n-896 2\n-848 10\n-878 50\n-864 2\n0 1000\n-934 6\n-792 4\n-271 153\n-917 1\n-891 3\n-833 107\n-847 3\n-758 2\n-754 2\n-892 2\n-738 2\n-876 2\n-52 64\n-882 2\n-270 154\n-763 3\n-868 72\n-846 4\n-427 3\n-771 3\n-767 17\n-852 2\n-765 1\n-772 6\n-831 1\n-582 2\n-910 6\n-772 12\n-764 2\n-907 9\n-909 7\n-578 2\n-872 2\n-848 2\n-528 412\n-731 3\n-879 1\n-862 4\n-909 1\n16 4\n-779 1\n-654 68\n510 490\n-921 3\n-773 5\n-653 69\n-926 2\n-737 3\n-919 1\n-841 1\n-863 3';
R=/(\S+) (\S+)/ym;N=1;i=w=l=0;for(X=[];m=R.exec(S);){X[N++]={w:j=m[2]*1,l:k=m[1]-j,r:k+2*j};l=k<l?k:l;w=j<w?w:j}M=[];X.map(x=>M[(x.l-l+1)*w-x.w]=x);s=[];M.map(x=>{while(i&&s[i-1].r<x.r)N+=s[--i].w?0:1;i&&(s[i-1].w-=x.w);s[i++]=x});while(i)N+=s[--i].w?0:1

ขาออก: 105

รุ่นก่อนหน้า

C=S.split('\n');N=1+C.shift()*1;s=[];C.map(x=>x.split(' ')).map(x=>[w=x[1]*1,x[i=0]*1+w]).sort((a,b)=>(c=a[1]-2*a[0])==(d=b[1]-2*b[0])?b[0]-a[0]:c-d).map(x=>{while(i&&s[i-1][1]<x[1])N+=s[--i][0]?0:1;i&&(s[i-1][0]-=x[0]);s[i++]=x});while(i)N+=s[--i][0]?0:1

ด้วยความคิดเห็น:

C=S.split('\n');                    // Split the input into an array on the newlines.
                                    // O(N)
N=1+C.shift()*1;                    // Remove the head of the array and store the value as
                                    // if there are N disjoint circles then there will be
                                    // N+1 regions.
                                    // At worst O(N) depending on how .shift() works.
s=[];                               // Initialise an empty stack.
                                    // O(1)
C .map(x=>x.split(' '))             // Split each line into an array of the two values.
                                    // O(1) per line = O(N) total.
  .map(x=>[w=x[1]*1,x[i=0]*1+w])    // Re-map the split values to an array storing the
                                    // radius and the right boundary.
                                    // O(1) per line = O(N) total.

  .sort((a,b)=>(c=a[1]-2*a[0])==(d=b[1]-2*b[0])?b[0]-a[0]:c-d)
                                    // Sort the circles on increasing left boundary and
                                    // then descending radius.
                                    // O(1) per comparison = O(N.log(N)) total.
  .map(x=>{                         // Loop through each circle
    while(i&&s[i-1][1]<x[1])        // Check to see if the current circle  is to the right
                                    // of the circles on the stack;
      N+=s[--i][0]?0:1;             // if so, decrement the length of the stack and if the
                                    // circle that pops off has radius equal to the total
                                    // radii of its children then increment the number of
                                    // regions by 1.

                                    // Since there can be at most N items on the stack then
                                    // there can be at most N items popped off the stack
                                    // over all the iterations; therefore this operation
                                    // has an O(N) total cost.
    i&&(s[i-1][0]-=x[0]);           // If there is a circle on the stack then this circle
                                    // is its child. Decrement the parent's radius by the
                                    // current child's radius.
                                    // O(1) per iteration
    s[i++]=x                        // Add the current circle to the stack.
  });
while(i)N+=s[--i][0]?0:1            // Finally, remove all the remaining circles from the
                                    // stack and if the circle that pops off has radius
                                    // equal to the total radii of its children then
                                    // increment the number of regions by 1.
                                    // Since there will always be at least one circle on the
                                    // stack then this has the added bonus of being the final
                                    // command so the value of N is printed to the console.
                                    // As per the previous comment on the complexity, there
                                    // can be at most N items on the stack so between this
                                    // and the iterations over the circles then there can only
                                    // be N items popped off the stack so the complexity of
                                    // all these tests on the circles on the stack is O(N).

ความซับซ้อนของเวลาทั้งหมดคือ O (N) สำหรับทุกสิ่งยกเว้นการเรียงลำดับที่เป็น O (N.log (N)) - อย่างไรก็ตามการแทนที่ด้วยชุดการจัดเรียงจะช่วยลดความซับซ้อนทั้งหมดเป็น O (N)

หน่วยความจำที่ต้องการคือ O (N)

คาดเดาสิ่งที่อยู่ถัดไปในรายการสิ่งที่ต้องทำของฉัน ... การจัดเรียงกลุ่มด้วยอักขระน้อยกว่า 150 ตัว เสร็จสิ้น


Bucket sort มีความซับซ้อนโดยเฉลี่ยเท่านั้นO(n)(ในความเป็นจริงO(n+k)) แต่O(n^2)หรือO(n log n)กรณีที่เลวร้ายที่สุดขึ้นอยู่กับอัลกอริทึมการเรียงลำดับที่ใช้ภายในที่เก็บข้อมูลดังนั้นคุณต้องดำเนินการด้วยอักขระ 50 ตัว
Martin Ender

@ m.buettner - การเรียงลำดับ Bucket สามารถทำได้ใน O (N) กรณีที่ซับซ้อนที่สุด มันขึ้นอยู่กับการเลือกอย่างระมัดระวังของถังและอัลกอริทึม O (1) เพื่อกำหนดให้กับถัง ฉันเคยทำมาก่อน (และพิสูจน์แล้ว) และฉันต้องการโอนรหัสไปยัง JavaScript อัลกอริทึมข้างต้นเป็น O (N.log (N)) ดังนั้นการปรับปรุงเพียงอย่างเดียวคือการรับอัลกอริทึมการเรียงลำดับ O (N)
MT0

ฉันสนใจที่จะพิสูจน์และเลือกถังที่เกี่ยวข้อง :)
Martin Ender

cs.princeton.edu/~dpd/Papers/SCG-09-invited/… (หน้า 556) แสดงตัวอย่างของการเรียงลำดับกลุ่มข้อมูล O (N) archive.org/stream/PlanarityTestingByPathAddition/ (หน้า 75) แสดงตัวอย่างของการค้นหา DFS รวมกันและการเรียงลำดับ DFS (ความซับซ้อนของเวลาถูกกล่าวถึงในหน้า 76)
MT0

1
@ Mt0 ค้างไว้ที่นั่นคุณอาจจะอ่านการเพิ่มของฉันในส่วนความซับซ้อนของคำถาม ด้วยจำนวนที่ไม่ จำกัด จำนวนการเรียงลำดับในเวลาเชิงเส้นจึงเป็นไปไม่ได้แน่นอนที่สุด
Niklas B.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.