每次做计算几何题都要做好久

考虑每个圆对答案的贡献,也就是每个圆被后面圆覆盖还有多少

可以把覆盖当成盖住一段弧度,看最后有多少没被覆盖

这就相当于线段覆盖问题了,

推推公式,算极角然后排序即可

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.
View Code

 

posted on 2015-06-30 09:47  acphile  阅读(174)  评论(0编辑  收藏  举报