# BZOJ[1043] 下落的圆盘

/*cmath库*/ 1 #include <cmath>
2 #include <cstdio>
3 #include <cstring>
4 #include <cstdlib>
5 #include <iostream>
6 #include <algorithm>
7 # define maxn 1010
8 # define pi  3.14159265358
9 using namespace std;
10 void ot(){cout<<"***"<<endl;}
11 int n;
12 struct Cir{
13     double x,y,r;
14 }g[maxn];
15 void init(){
16     scanf("%d",&n);
17     for(int i=1;i<=n;i++) scanf("%lf%lf%lf",&g[i].r,&g[i].x,&g[i].y);
18 }
19 bool Cro(int i,int j){
20     double dis=sqrt((g[i].x-g[j].x)*(g[i].x-g[j].x) + (g[i].y-g[j].y)*(g[i].y-g[j].y));
21     if(dis<g[i].r+g[j].r && dis>fabs(g[i].r-g[j].r)) return 1;
22     return 0;
23 }
24 struct Cov{
25     double l,r;
26 }C[maxn];
27 double find(int i,int j){
28     double dis=sqrt((g[i].x-g[j].x)*(g[i].x-g[j].x) + (g[i].y-g[j].y)*(g[i].y-g[j].y));
29     double ret=acos((g[i].r*g[i].r+dis*dis-g[j].r*g[j].r) / (2.0*g[i].r*dis));
30     return ret;
31 }
32 bool cmp(const Cov a,const Cov b){
33     if(a.l==b.l) return a.r<b.r;
34     return a.l<b.l;
35 }
36 bool Nei(int i,int j){
37     double dis=sqrt((g[i].x-g[j].x)*(g[i].x-g[j].x) + (g[i].y-g[j].y)*(g[i].y-g[j].y));
38     if(g[j].r>=g[i].r){
39         if(dis<=g[j].r-g[i].r) {
40             return 1;
41         }
42     }
43     return 0;
44 }
45 void work(){
46     int cnt;
47     double ans=0.0;
48     for(int i=1;i<=n;i++){
49         cnt=0; bool pd=0;
50         for(int j=i+1;j<=n;j++){
51             if(Nei(i,j)){
52                 pd=1; break;
53             }
54             if(Cro(i,j)){
55                 double jiao1=atan2(g[j].y-g[i].y,g[j].x-g[i].x);
56                 if(jiao1<0) jiao1=2*pi+jiao1;
57                 double jiao2=find(i,j);
58                 C[++cnt].l=jiao1-jiao2; C[cnt].r=jiao1+jiao2;
59                 if(C[cnt].l<0){
60                     cnt++;
61                     C[cnt].l=C[cnt-1].l+2*pi; C[cnt].r=2*pi; C[cnt-1].l=0.0;
62                 }
63                 if(C[cnt].r>2*pi){
64                     cnt++;
65                     C[cnt].r=C[cnt-1].r-2*pi; C[cnt].l=0; C[cnt-1].r=2*pi;
66                 }
67             }
68         }
69         if(pd) continue;
70         sort(C+1,C+cnt+1,cmp);
71         double le=C[1].l,ri=C[1].r;
72         double now=0.0;
73         for(int j=2;j<=cnt;j++){
74             if(C[j].l<=ri) ri=max(ri,C[j].r);
75             else{
76                 now+=ri-le;
77                 le=C[j].l; ri=C[j].r;
78             }
79         }
80         now+=ri-le;
81         if(cnt==0) now=0.0;
82         double len=g[i].r*(2*pi-now);
83         ans+=len;
84     }
85     printf("%.3lf\n",ans);
86 }
87 int main(){
88     init();
89     work();
90 }

posted @ 2017-10-06 11:26  Nawox  阅读(121)  评论(0编辑  收藏  举报