您的位置:首页 > 其它

bzoj 2178: 圆的面积并

2014-11-06 22:58 176 查看

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: