bzoj 2178: 圆的面积并

来源:互联网 发布:叮叮摩卡数据无法打开 编辑:程序博客网 时间:2024/05/17 06:20

Description

给出N个圆,求其面积并

Input

先给一个数字N ,N< = 1000 接下来是N行是圆的圆心,半径,其绝对值均为小于1000的整数

Output

面积并,保留三位小数

自适应辛普森。。留个模板好了
#include<cmath>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;const double eps=1e-13;struct circle{     double x,y;     double r;};circle a[1001],cir[1001];struct loc{ double rd; double x,y;     double l,r;}sx[1001];struct line{     double l,r;}px[1001];int p;int st,se;inline bool cmp1(circle x,circle y){     if(x.r<y.r)          return true;     return false;}inline bool cmp2(circle x,circle y){     if(x.x-x.r<y.x-y.r)          return true;     return false;}inline bool cmp3(line x,line y){ if(x.l<y.l)      return true;     return false;}inline double fabs(double x){     if(x<0)          x=-x;     return x;}inline double dist(int i,int j){     return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));}inline double geth(double x){     int pp=0;     int i,j;     double len=0,dis;     for(i=st;i<=se;i++)     {          if(sx[i].l>=x||sx[i].r<=x)               continue;          dis=sqrt(sx[i].rd*sx[i].rd-(x-sx[i].x)*(x-sx[i].x));          pp++;          px[pp].l=sx[i].y-dis;          px[pp].r=sx[i].y+dis;     }     sort(px+1,px+1+pp,cmp3);     double r;     for(i=1;i<=pp;i++)     {          r=px[i].r;          for(j=i+1;j<=pp;j++)          {               if(px[j].l>r)                    break;               if(px[j].r>r)                    r=px[j].r;          }          len+=r-px[i].l;          i=j-1;     }     return len;}inline double cal(double len,double lh,double mh,double rh){     return (lh+mh*(double)4+rh)*len/(double)6;}inline double simpson(double l,double mid,double r,double lh,double mh,double rh,double s){     double mid1,mid2;     mid1=(l+mid)/(double)2;     mid2=(mid+r)/(double)2;     double mh1=geth(mid1),mh2=geth(mid2);     double s1=cal(mid-l,lh,mh1,mh),s2=cal(r-mid,mh,mh2,rh);     if(fabs(s1+s2-s)<eps)          return s1+s2;     return simpson(l,mid1,mid,lh,mh1,mh,s1)+simpson(mid,mid2,r,mh,mh2,rh,s2);}bool flag[1001];int main(){     int n;     scanf("%d",&n);     memset(flag,false,sizeof(flag));     int i,j;     for(i=1;i<=n;i++)          scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].r);     sort(a+1,a+1+n,cmp1);     for(i=1;i<=n;i++)     {          for(j=i+1;j<=n;j++)          {               if(dist(i,j)<a[j].r-a[i].r)               {                    flag[i]=true;                    break;               }          }     }     for(i=1;i<=n;i++)     {          if(!flag[i])          {               p++;               cir[p]=a[i];          }     }     sort(cir+1,cir+1+p,cmp2);     for(i=1;i<=p;i++)     {       sx[i].x=cir[i].x;       sx[i].y=cir[i].y;       sx[i].rd=cir[i].r;          sx[i].l=cir[i].x-cir[i].r;          sx[i].r=cir[i].x+cir[i].r;     }     double l,r,mid,lh,rh,mh;     double ans=0;     for(i=1;i<=p;i++)     {          l=sx[i].l;  r=sx[i].r;          for(j=i+1;j<=p;j++)          {               if(sx[j].l>r)                    break;               if(sx[j].r>r)                    r=sx[j].r;          }          st=i;          se=j-1;          i=j-1;          mid=(l+r)/(double)2;          lh=geth(l);          rh=geth(r);          mh=geth(mid);          ans+=simpson(l,mid,r,lh,mh,rh,cal(r-l,lh,mh,rh)); } printf("%.3lf\n",ans);     return 0;}


1 0
原创粉丝点击