Description
给出N个圆,求其面积并
【题目分析】
Simpson积分模板题。其实程序有BUG,懒得写了。
其实就是不断的二分,到一个较小值的时候,就可以了。
【代码】
#include<cmath>
#include<cstdio>
#include<algorithm>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define inf 1e9
#define eps 1e-7
using namespace std;
int n,tot;
bool tag[1001];
struct circle{double x,y,r;}a[1001],b[1001];
struct segment{double l,r;}p[1001];
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline bool cmpc(circle a,circle b)
{
return a.r<b.r;
}
inline bool cmp(segment a,segment b)
{
return a.l==a.r?a.r<b.r:a.l<b.l;
}
inline double get(double x)
{
int cnt=0;
F(i,1,n) if (fabs(x-a[i].x)<=a[i].r-eps)
{
double tmp=sqrt(a[i].r*a[i].r-(x-a[i].x)*(x-a[i].x));
p[++cnt]=(segment){a[i].y-tmp,a[i].y+tmp};
}
sort(p+1,p+cnt+1,cmp);
double h=-1e9,ans=0;
F(i,1,cnt)
{
if (h<p[i].l) ans+=p[i].r-p[i].l,h=p[i].r;
else if (h<p[i].r) ans+=p[i].r-h,h=p[i].r;
}
return ans;
}
inline double calc(double l,double r)
{
double mid=(l+r)/2;
return (get(l)/6+get(mid)*2/3+get(r)/6)*(r-l);
}
inline double simpson(double l,double r)
{
double mid=(l+r)/2,s1=calc(l,r),s2=calc(l,mid)+calc(mid,r);
if (fabs(s2-s1)<=eps) return s2;
else return simpson(l,mid)+simpson(mid,r);
}
int main()
{
n=read();
F(i,1,n) b[i].x=read(),b[i].y=read(),b[i].r=read();
sort(b+1,b+n+1,cmpc);
F(i,1,n-1) F(j,i+1,n)
if ((b[i].x-b[j].x)*(b[i].x-b[j].x)+(b[i].y-b[j].y)*(b[i].y-b[j].y)<=(b[i].r-b[j].r)*(b[i].r-b[j].r))
{
tag[i]=true;
break;
}
F(i,1,n) if (!tag[i]) a[++tot]=b[i];
n=tot;
printf("%.3lf\n",simpson(-2000.0,2000.0));
return 0;
}