SPOJ CIRU The area of the union of circles

You are given N circles and expected to calculate the area of the union of the circles !

Input

The first line is one integer n indicates the number of the circles. (1 <= n <= 1000)

Then follows n lines every line has three integers

Xi Yi Ri

indicates the coordinate of the center of the circle, and the radius. (|Xi|. |Yi|  <= 1000, Ri <= 1000)

Note that in this problem Ri may be 0 and it just means one point !

Output

The total area that these N circles with 3 digits after decimal point

Example

Input:
3
0 0 1
0 0 1
100 100 1


Output:
6.283

 

simpson自适应积分法

精度只需要1e-6,十分友好

调试语句懒得删

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 using namespace std;
  7 const double eps=1e-6;
  8 const int INF=1e9;
  9 const int mxn=1010;
 10 int read(){
 11     int x=0,f=1;char ch=getchar();
 12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 13     while(ch>='0' && ch<='9'){x=x*10-'0'+ch;ch=getchar();}
 14     return x*f;
 15 }
 16 //
 17 struct cir{
 18     double x,y,r;
 19     friend bool operator < (const cir a,const cir b){return a.r<b.r;}
 20 }c[mxn];int cnt=0;
 21 inline double dist(cir a,cir b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
 22 //
 23 struct line{
 24     double l,r;
 25     friend bool operator <(const line a,const line b){return a.l<b.l;}
 26 }a[mxn],b[mxn];int lct=0;
 27 double f(double x){
 28     int i,j;
 29     lct=0;
 30     for(i=1;i<=cnt;i++){//计算直线截得圆弧长度 
 31         if(fabs(c[i].x-x)>=c[i].r)continue;
 32         double h= sqrt(c[i].r*c[i].r-(c[i].x-x)*(c[i].x-x));
 33         a[++lct].l=c[i].y-h;
 34         a[lct].r=c[i].y+h;
 35     }
 36     if(!lct)return 0;
 37     double len=0,last=-INF;
 38     sort(a+1,a+lct+1);
 39     for(i=1;i<=lct;i++){//线段长度并 
 40         if(a[i].l>last){len+=a[i].r-a[i].l;last=a[i].r;}
 41         else if(a[i].r>last){len+=a[i].r-last;last=a[i].r;}
 42     }
 43 //    printf("x:%.3f  len:%.3f\n",x,len);
 44     return len;
 45 }
 46 inline double sim(double l,double r){
 47     return (f(l)+4*f((l+r)/2)+f(r))*(r-l)/6;
 48 }
 49 double solve(double l,double r,double S){
 50     double mid=(l+r)/2;
 51     double ls=sim(l,mid);
 52     double rs=sim(mid,r);
 53     if(fabs(rs+ls-S)<eps)return ls+rs;
 54     return solve(l,mid,ls)+solve(mid,r,rs);
 55 }
 56 int n;
 57 double ans=0;
 58 bool del[mxn];
 59 int main(){
 60     n=read();
 61     int i,j;
 62     double L=INF,R=-INF;
 63     for(i=1;i<=n;i++){
 64         c[i].x=read();    c[i].y=read();    c[i].r=read();
 65 //        L=min(L,c[i].x-c[i].r);
 66 //        R=max(R,c[i].x+c[i].r);
 67     }
 68     //
 69     sort(c+1,c+n+1);
 70     for(i=1;i<n;i++)
 71         for(j=i+1;j<=n;j++){
 72 //            printf("%d %.3f %.3f %.3f %.3f\n",j,c[j].x,c[i].r,c[j].r,dist(c[i],c[j]));
 73             if(c[j].r-c[i].r>=dist(c[i],c[j]))
 74                 {del[i]=1;break;}
 75         }
 76     for(i=1;i<=n;i++)
 77         if(!del[i])c[++cnt]=c[i];
 78     //删去被包含的圆
 79 //    printf("cnt:%d\n",cnt);
 80     double tmp=-INF;int blct=0;
 81     for(i=1;i<=cnt;i++){
 82         b[++blct].l=c[i].x-c[i].r;
 83         b[blct].r=c[i].x+c[i].r;
 84     }
 85     sort(b+1,b+blct+1);
 86 //    printf("lct:%d\n",blct);
 87 //    int tlct=t;
 88     for(i=1;i<=blct;i++){
 89 //        printf("%.3f %.3f\n",b[i].l,b[i].r);
 90 //        printf("tmp:%.3f\n",tmp);
 91         if(b[i].r<=tmp)continue;
 92         L=max(tmp,b[i].l);
 93 //        printf("%d: %.3f %.3f\n",i,L,a[i].r);
 94         ans+=solve(L,b[i].r,sim(L,b[i].r));
 95 //        printf("ANS:%.3f\n",ans);
 96 //        printf("nlct:%d\n",lct);
 97         tmp=b[i].r;
 98     }
 99     
100     
101 //    ans=solve(L,R,f((L+R)/2));
102     printf("%.3f\n",ans);
103     return 0;
104 }

 

posted @ 2017-01-26 18:11  SilverNebula  阅读(240)  评论(0编辑  收藏  举报
AmazingCounters.com