Tìm khu vực độc quyền trong giao lộ Circle


17

Đây là một câu đố hình học đầy thách thức cho bạn!

Đưa ra một vòng tròn Ancác vòng tròn khác B[n], tìm tổng diện tích chứa trong Ađó không nằm trong bất kỳ vòng tròn nào B.

Mã của bạn nên càng ngắn càng tốt.

Đầu vào

Đầu vào của bạn nên chứa thông tin sau:

  • Một số dấu phẩy động để biểu thị bán kính hình tròn A.
  • Một danh sách các số dấu phẩy động để biểu thị bán kính của các vòng tròn trong B.
  • Một danh sách các trung tâm của các vòng tròn trong B . Chương trình của bạn có thể mong đợi các trung tâm theo tọa độ cực hoặc Cartesian.
  • Tùy chọn, bạn có thể nhận được số lượng nvòng tròn trong B. Đầu vào này là không bắt buộc.

Nó sẽ được giả định rằng trung tâm của vòng tròn A là gốc tọa độ, nghĩa là điểm (0, 0).

Nó được đảm bảo rằng không có hai vòng tròn Bgiống hệt nhau, nhưng không đảm bảo rằng: tất cả các vòng tròn Bgiao nhau A, tất cả các trung tâm Bđều ở bên ngoàiA hoặc không có hai vòng tròn nào Bgiao nhau. Đảm bảo rằng giải pháp của bạn có thể xử lý các trường hợp cạnh khác nhau.

Bạn có thể nhận đầu vào theo bất kỳ thứ tự nào và ở dạng nhập văn bản (thông qua stdin hoặc tương đương với ngôn ngữ của bạn), tham số chức năng hoặc đối số dòng lệnh.

Nếu bạn chọn nhận đầu vào văn bản, cần có một hoặc hai ký tự phân cách ASCII có thể in giữa các phần đầu vào.

Đầu ra

Chương trình hoặc chức năng của bạn sẽ xuất ra một số dấu phẩy động đơn biểu thị tổng diện tích Akhông nằm trong bất kỳ vòng tròn nào B. Câu trả lời của bạn phải chính xác với ít nhất ba con số quan trọng cho tất cả các trường hợp thử nghiệm.

Quy tắc chung áp dụng.

Giải pháp của bạn không nên dựa vào các điểm lấy mẫu trong vòng tròn để xác định khu vực.

Các phần tử tích hợp tự động định vị các giao điểm của các vòng tròn, tìm các khu vực trong các giao điểm của các vòng tròn hoặc giải quyết vấn đề này ngay lập tức không được phép.

Các trường hợp thử nghiệm

Trong mỗi hình ảnh, vòng tròn Ađược viền màu xanh lam, với các vòng tròn được Bviền màu xanh lá cây và màu đen. Khu vực cần được trả lại được lấp đầy màu đỏ.

(Cảm ơn đặc biệt đến Rainer P. vì đã kiểm tra các giải pháp của tôi)

Trường hợp thử nghiệm 1:

A = {x: 0, y: 0, rad: 50}
B[0] = {x: 0, y: 0, rad: 100}

Trường hợp kiểm tra 1

Result: 0.00

Trường hợp thử nghiệm 2:

A = {x: 0, y: 0, rad: 100.000000}
B[0] = {x: 100.000000, y: 0.000000, rad: 50.000000}
B[1] = {x: 30.901699, y: -95.105652, rad: 50.000000}
B[2] = {x: -80.901699, y: -58.778525, rad: 50.000000}
B[3] = {x: -80.901699, y: 58.778525, rad: 50.000000}
B[4] = {x: 30.901699, y: 95.105652, rad: 50.000000}

Trường hợp thử nghiệm 2

Result: 1.3878e+04

Trường hợp thử nghiệm 3:

A = {x: 0, y: 0, rad: 138}
B[0] = {x: 100, y: 0, rad: 100}
B[1] = {x: -50, y: -86, rad: 100} 
B[2] = {x: -93, y: 135, rad: 50}

Trường hợp thử nghiệm 3

Result: 1.8969e+04

Trường hợp thử nghiệm 4:

A = {x: 0, y: 0, rad: 121.593585}
B[0] = {x: 81.000000, y: 107.000000, rad: 59.841457}
B[1] = {x: -152.000000, y: -147.000000, rad: 50.000000}
B[2] = {x: 43.000000, y: -127.000000, rad: 105.118980}
B[3] = {x: 0.000000, y: -72.000000, rad: 57.870545}
B[4] = {x: -97.000000, y: -81.000000, rad: 98.488578}
B[5] = {x: -72.000000, y: 116.000000, rad: 66.468037}
B[6] = {x: 2.000000, y: 51.000000, rad: 50.000000}

Trường hợp thử nghiệm 4

Result: 1.1264e+04

Trường hợp thử nghiệm 5:

A = {x: 0, y: 0, rad: 121.605921}
B[0] = {x: 0.000000, y: -293.000000, rad: 250.000000}
B[1] = {x: 0.000000, y: -56.000000, rad: 78.230429}
B[2] = {x: 0.000000, y: -102.000000, rad: 100.000000}

Trường hợp thử nghiệm 5

Result: 2.6742e+04

Cách đọc được đề nghị:

Fewell, MP "Khu vực chồng chéo chung của ba vòng tròn." Tháng 10 năm 2006. Web. http://dspace.dsto.defence.gov.au/dspace/bitstream/1947/4551/4/DSTO-TN-0722.PR.pdf .


Tôi đã cố gắng tự giải quyết vấn đề này hai năm trước khi làm việc này , dựa trên vấn đề đơn giản như thế nào đối với hai vòng tròn. Cuối cùng tôi đã đọc được bài báo mà bạn liên kết ... và quyết định đi cùng khu vực Monte Carlo. "Giải pháp của bạn không nên dựa vào các điểm lấy mẫu trong vòng tròn để xác định khu vực." Đ:
Martin Ender

Bạn dường như không có trường hợp thử nghiệm trong đó một vòng tròn Bchứa một vòng tròn khác. Có thể đáng để thêm vào đó.
Martin Ender

Bạn có thể kiểm tra trường hợp thử nghiệm thứ ba của bạn? Tôi đang nhận được 1.8970e+04.
LegionMammal978

@ MartinBüttner Tôi cũng gặp phải vấn đề về tai nạn. Tôi không quá hài lòng với giải pháp của mình, nhưng nó có vẻ hiệu quả. Tôi sẽ cố gắng rút ra một bài kiểm tra nhỏ cho trường hợp đó, cảm ơn!
BrainSteel

@ LegionMammal978 Vâng, có vẻ như trường hợp đó là sai. Tôi có các dữ liệu sau cho nút giao thông giữa vòng tròn: B[0] - A intersection: 20653.659515, B[1] - A intersection: 20757.824115, B[1] - B[0] intersection: 1841.847766, B[2] - A intersection: 1289.164541, trong đó sản lượng 18969.69009là câu trả lời.
BrainSteel

Câu trả lời:


14

Python 2, 631 byte

from cmath import*
C=input()
O,R=C[0]
def I(p,r,q,s):
 try:q-=p;d=abs(q*q);x=(r*r-s*s+d)/d/2;return[p+q*(x+z*(r*r/d-x*x)**.5)for z in-1j,1j]
 except:return[]
S=sorted
V=S(i.real for p,r in C for c in C for i in[p-r,p+r]+I(p,r,*c)if-R<=(i-O).real<=R)
A=pi*R*R
for l,r in zip(V,V[1:]):
 H=[]
 for p,t in C:
    try:
     for s in-1,1:a,b=[p.imag+s*(t*t-(p.real-x)**2)**.5for x in l,r];H+=[a+b,a,b,s,t,p],
    except:0
 a,b=H[:2];H=S(H[2:]);n=0;c=a
 for d in H:
    s=d[3];z=.5;H*=d<b
    for q,w,e,_,t,y in(c,min(d,b))*(n-s<(a<d)or[0]*n>H):\
g=phase((l+w*1j-y)/(r+e*1j-y));A-=abs(g-sin(g)).real*t*t/2-z*q*(r-l);z=-z
    n-=s
    if(a<d)*s*n==-1:c=d
print A

Các ngắt dòng đi trước \là để dễ đọc và không được tính vào điểm số.

Đọc đầu vào thông qua STDIN dưới dạng danh sách các (center, radius)cặp, trong đó centercó một số phức trong biểu mẫu X+Yj. Vòng tròn đầu tiên trong danh sách là A (có trung tâm không phải ở gốc) và phần còn lại của danh sách là B . In kết quả sang STDOUT.

Thí dụ

Input:  (0+0j, 138),  (100+0j, 100), (-50+-86j, 100), (-93+135j, 50)
Output: 18969.6900901

Giải trình

Đây là một biến thể (dài hơn và xấu hơn nhiều: P) trong giải pháp của tôi đối với Khu vực đa giác tự giao của Martin Büttner thách thức . Nó sử dụng cùng một thủ thuật để phá vỡ vấn đề thành những mảnh nhỏ, đủ để nó trở nên dễ quản lý hơn.

Chúng tôi tìm thấy các điểm giao nhau giữa tất cả các cặp vòng tròn (xem xét cả A và các vòng tròn trong B ) và truyền một đường thẳng đứng qua mỗi vòng tròn . Ngoài ra, chúng tôi chuyển tất cả các đường thẳng đứng tiếp tuyến với bất kỳ vòng tròn nào. Chúng tôi vứt bỏ tất cả các dòng mà không làm giao nhau Một , do đó tất cả các dòng còn lại là giữa các tiếp tuyến bên trái và bên phải của A .

Hình 1

Chúng tôi đang tìm kiếm các khu vực giao lộ của A và công đoàn của các vòng tròn trong B -the đậm vùng màu đỏ trong hình minh họa ở trên. Đây là khu vực mà chúng ta phải trừ A để có kết quả.

Giữa mỗi cặp đường thẳng đứng liên tiếp, khu vực này có thể được chia thành một tập hợp các hình thang thẳng đứng (hoặc hình tam giác hoặc đoạn thẳng, như trường hợp đặc biệt của hình thang), với một đoạn cung "thừa" bên cạnh mỗi chân. Thực tế là chúng ta vượt qua nhiều đường thẳng đứng như chúng ta đảm bảo rằng vùng giới hạn thực sự không phức tạp hơn thế, vì nếu không sẽ phải có thêm một điểm giao nhau, và do đó có một đường thẳng đứng bổ sung, giữa hai đường thẳng trong câu hỏi

Hình 2

Để tìm các hình thang và các cung tròn này, với mỗi cặp đường thẳng đứng liên tiếp, chúng tôi tìm các phân đoạn cung của mỗi vòng tròn nằm chính xác giữa hai đường này (tất nhiên, một số vòng tròn có thể không có phân đoạn cung giữa một cặp đường thẳng cho trước .) Trong hình minh họa bên dưới, đây là sáu đoạn cung màu vàng (sáng và tối), khi xem xét hai đường thẳng đứng màu đỏ. Lưu ý rằng, vì chúng ta chuyển tất cả các đường thẳng đứng tiếp tuyến với các vòng tròn, nếu một vòng tròn có một đoạn cung nằm giữa hai đường, nó nhất thiết phải giao nhau cả hai đường, điều này giúp đơn giản hóa phần còn lại của thuật toán.

Không phải tất cả các cung này đều có liên quan; chúng tôi chỉ quan tâm đến các shortcut này nằm trên ranh giới của ngã tư giữa A và công đoàn của B . Để tìm ra chúng, chúng tôi sắp xếp các cung từ trên xuống dưới (lưu ý rằng các cung có thể không giao nhau đúng cách, vì điều này có nghĩa là sự tồn tại của một đường thẳng đứng khác giữa hai chúng tôi đang xem xét, và vì vậy thật hợp lý khi nói chuyện về một cung tùy ý ở trên hoặc dưới, bất kỳ cung nào khác.)

Hình 3

Chúng tôi đi qua các cung, theo thứ tự, trong khi vẫn giữ số lượng vòng tròn B chúng tôi hiện đang ở bên trong, n . Nếu n thay đổi từ 0 thành 1 trong khi chúng ta ở trong A hoặc nếu chúng ta ở cung trên cùng của A trong khi n không khác, thì cung hiện tại tương ứng với một chân của hình thang. Nếu n thay đổi từ 1 thành 0 trong khi chúng ta ở trong A hoặc nếu chúng ta ở cung dưới cùng của A trong khi nlà khác không, thì cung hiện tại tương ứng với chân kia của cùng một hình thang. Một khi chúng ta tìm thấy một cặp vòng cung (hai vòng cung màu vàng sáng trong hình minh họa ở trên), chúng tôi tính toán diện tích của hình thang tương ứng, và trong hai phân đoạn vòng cung, và thêm nó vào tổng diện tích được trừ vào Một .

Tính diện tích của A , cũng như diện tích của các hình thang, khá thẳng về phía trước. Diện tích của mỗi đoạn cung là diện tích của cung tròn tương ứng, trừ diện tích tam giác có các đỉnh là hai điểm cuối của đoạn cung và tâm của đường tròn tương ứng.

hinh 4


1
Đây là loại giải pháp tôi đang xem xét, ngoại trừ tôi sẽ tìm thấy khu vực mục tiêu trực tiếp bằng cách tìm các triarcs và bẫy trong A nhưng không phải B (có thể tìm thấy các khu vực bằng cách trừ một đoạn cung từ hình tam giác hoặc hình thang).
quintopia

@quintopia Điều này thậm chí có thể ngắn hơn một chút, vì nó giúp chúng ta tiết kiệm được nhu cầu tính diện tích của A , và tất cả những gì nó có thể là chơi một chút với điều kiện trên n .
Ell

@quintopia OTOH, bạn sẽ phải tính đến khả năng có một vòng cung dương bên cạnh một trong hai chân, nếu đó là một đoạn cung của A , vì vậy ai biết được ...
Ell

Giải pháp tuyệt vời. Một vấn đề gần như giống hệt như vậy đã bị mắc kẹt trong đầu tôi đêm qua, và tôi thực sự muốn ai đó giải quyết nó. Giải pháp của bạn tốt hơn là những ý tưởng tôi đã làm việc với.
Logic Knight
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.