每次做计算几何题都要做好久
考虑每个圆对答案的贡献,也就是每个圆被后面圆覆盖还有多少
可以把覆盖当成盖住一段弧度,看最后有多少没被覆盖
这就相当于线段覆盖问题了,
推推公式,算极角然后排序即可
md,pascal算极角就是麻烦
1 uses math; 2 const pi=3.1415926535897932384626433832795; 3 eps=1e-4; 4 type node=record 5 l,r:double; 6 end; 7 8 var q:array[0..2010] of node; 9 x,y,r:array[0..2010] of double; 10 t,j,i,n:longint; 11 ans:double; 12 13 function dis(i,j:longint):double; 14 begin 15 exit(sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j]))); 16 end; 17 18 function have(i,j:longint):boolean; 19 begin 20 exit(r[j]-r[i]>=dis(i,j)); 21 end; 22 23 procedure swap(var a,b:node); 24 var c:node; 25 begin 26 c:=a; 27 a:=b; 28 b:=c; 29 end; 30 31 function get(x,y:double):double; 32 begin 33 if x=0 then 34 begin 35 if y>0 then exit(pi/2) 36 else exit(-pi/2); 37 end; 38 get:=arctan(y/x); 39 if (x<0) then get:=get+pi; 40 end; 41 42 procedure sort(l,r:longint); 43 var i,j:longint; 44 x:double; 45 begin 46 i:=l; 47 j:=r; 48 x:=q[(l+r) shr 1].l; 49 repeat 50 while q[i].l<x do inc(i); 51 while x<q[j].l do dec(j); 52 if not(i>j) then 53 begin 54 swap(q[i],q[j]); 55 inc(i); 56 dec(j); 57 end; 58 until i>j; 59 if l<j then sort(l,j); 60 if i<r then sort(i,r); 61 end; 62 63 function cal(j:longint):double; 64 var i:longint; 65 d,now,l,z,an:double; 66 begin 67 for i:=j+1 to n do 68 if have(j,i) then exit(0); 69 t:=0; 70 for i:=j+1 to n do 71 begin 72 d:=dis(i,j); 73 if not have(i,j) and (r[j]+r[i]>d) then 74 begin 75 inc(t); 76 an:=get(x[i]-x[j],y[i]-y[j]); 77 l:=(sqr(r[j])-sqr(r[i])+sqr(d))/(2*d); 78 z:=arccos(l/r[j]); 79 q[t].l:=an-z; 80 q[t].r:=an+z; 81 // writeln(an,' ',z,' ',i,' ',x[i]-x[j],' ',y[i]-y[j]); 82 // readln; 83 end; 84 end; 85 for i:=1 to t do 86 begin 87 if q[i].l>2*pi then q[i].l:=q[i].l-2*pi; 88 if q[i].r>2*pi then q[i].r:=q[i].r-2*pi; 89 if q[i].l<0 then q[i].l:=q[i].l+2*pi; 90 if q[i].r<0 then q[i].r:=q[i].r+2*pi; 91 if q[i].l>q[i].r then 92 begin 93 inc(t); 94 q[t].l:=0; 95 q[t].r:=q[i].r; 96 q[i].r:=2*pi; 97 end; 98 end; 99 sort(1,t); 100 cal:=0; 101 now:=0; 102 for i:=1 to t do 103 if q[i].l>now then 104 begin 105 cal:=cal+(q[i].l-now); 106 now:=q[i].r; 107 end 108 else if now<q[i].r then now:=q[i].r; 109 110 cal:=cal+2*pi-now; 111 if cal<0 then cal:=0; 112 cal:=cal*r[j]; 113 end; 114 115 begin 116 readln(n); 117 for i:=1 to n do 118 readln(r[i],x[i],y[i]); 119 120 for i:=1 to n do 121 ans:=ans+cal(i); 122 123 writeln(ans:0:3); 124 end.