[HAOI2008]下落的圆盘

Description

  有n个圆盘从天而降,后面落下的可以盖住前面的。求最后形成的封闭区域的周长。看下面这副图, 所有的红
色线条的总长度即为所求.

Input

  第一行为1个整数n,N<=1000
接下来n行每行3个实数,ri,xi,yi,表示下落时第i个圆盘的半径和圆心坐标.

Output

  最后的周长,保留三位小数

Sample Input

2
1 0 0
1 1 0

Sample Output

10.472
枚举每一个圆,看它有多少没有被覆盖。
每一个圆的极角可以拉直成一个长为2×pi的线段
然后套用数学公式,算出一个圆覆盖的范围
要注意讨论极角小于0的情况
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 struct ZYYS
 8 {
 9   double l,r;
10 }a[5001];
11 double pi=acos(-1.0);
12 int n;
13 double x[1001],y[1001],r[1001],ans;
14 bool cmp(ZYYS a,ZYYS b)
15 {
16   return a.l<b.l;
17 }
18 double dist(int i,int j)
19 {
20   return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
21 }
22 bool contain(int i,int j)
23 {
24   if (r[i]-r[j]>=dist(i,j)) return 1;
25   return 0;
26 }
27 double cal(int o)
28 {int i;
29   int cnt=0;
30   for (i=o+1;i<=n;i++)
31     if (contain(i,o)) return 0;
32   for (i=o+1;i<=n;i++)
33     {
34       if (contain(o,i)||dist(o,i)>=r[i]+r[o]) continue;
35       double d=dist(o,i);
36       double xt=acos((-r[i]*r[i]+r[o]*r[o]+d*d)/(2.0*d*r[o]));
37       double aef=atan2(y[i]-y[o],x[i]-x[o]);
38       a[++cnt]=(ZYYS){aef-xt,aef+xt};
39       if (a[cnt].l<0) a[cnt].l+=2*pi;
40       if (a[cnt].r<0) a[cnt].r+=2*pi;
41       if (a[cnt].l>a[cnt].r)
42     {
43       double p=a[cnt].l;                                                                                          
44       a[cnt].l=0;
45       a[++cnt].l=p;a[cnt].r=2*pi;
46     }
47     }
48   sort(a+1,a+cnt+1,cmp);
49   double res=0,now=0;
50   for (i=1;i<=cnt;i++)
51     {
52       if (a[i].l>now) res+=a[i].l-now,now=a[i].r;
53       now=max(now,a[i].r);
54     }
55   res+=2*pi-now;
56   return res*r[o];
57 }
58 int main()
59 {int i;
60   cin>>n;
61   for (i=1;i<=n;i++)
62     {
63       scanf("%lf%lf%lf",&r[i],&x[i],&y[i]);
64     }
65   for (i=1;i<=n-1;i++)
66     ans+=cal(i);
67   ans+=2*pi*r[n];
68   printf("%.3lf\n",ans);
69 }

 

posted @ 2018-01-11 16:10  Z-Y-Y-S  阅读(239)  评论(0编辑  收藏  举报