题目大意:给定n个圆,求面积并
直接暴力套用Simpson自适应公式就行了
对于每一个x值,求出F(x)的方法是求出所有圆在直线x=x(重了233)上的截取区间
然后求区间并 返回区间长度即是F值
这样正常写就过样例了 然后 WA了。。。
尼玛我样例都过了你跟我说WA?
下面是注意事项:
1.此题卡精度 EPS要设为1e-13 设为1e-12会WA
2.标程精度不够 不能用long double 否则会WA
3.这样会TLE 解决方法是预先将内含与其他圆的圆删掉 然后就能过了
这明显是卡数据啊- - 没办法了- -
此外顺便学习了一下类继承的东西- -
#include <map>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define M 1010
#define EPS 1e-13
using namespace std;
typedef double ld;
struct Point{
ld x,y;
Point() {}
Point(ld _,ld __):
x(_),y(__) {}
};
struct Circle:Point{
ld r;
void Read()
{
int x,y,r;
scanf("%d%d%d",&x,&y,&r);
this->x=x;
this->y=y;
this->r=r;
}
bool operator < (const Circle &c) const
{
return r < c.r;
}
}circles[M];
struct Interval{
ld l,r;
Interval() {}
Interval(ld _,ld __):
l(_),r(__) {}
bool operator < (const Interval &i) const
{
return l<i.l;
}
};
int n;
ld ans;
ld F(ld x)
{
static Interval intervals[M];
static map<ld,ld> a;
static map<ld,ld>::iterator it;
if( (it=a.find(x))!=a.end() )
return it->second;
int i,tot=0;
ld& re=a[x];
memset(intervals,0,sizeof intervals);
for(i=1;i<=n;i++)
{
ld dis=fabs(x-circles[i].x);
if( dis>=circles[i].r )
continue;
ld delta=sqrt(circles[i].r*circles[i].r-dis*dis);
intervals[++tot]=Interval(circles[i].y-delta,circles[i].y+delta);
}
if(!tot) return re=0.0;
sort(intervals+1,intervals+tot+1);
ld temp=-1e5;
for(i=1;i<=tot;i++)
{
if(intervals[i].r<=temp)
continue;
re+=intervals[i].r-max(intervals[i].l,temp);
temp=intervals[i].r;
}
return re;
}
ld Simpson_Integral(ld l,ld r)
{
ld mid=(l+r)/2.0;
return (r-l)*(F(l)+F(r)+4.0*F(mid))/6.0;
}
ld Self_Adjusted_Simpson_Integral(ld l,ld r,ld area)
{
ld mid=(l+r)/2.0;
ld l_area=Simpson_Integral(l,mid);
ld r_area=Simpson_Integral(mid,r);
if(fabs(l_area+r_area-area)<EPS)
return l_area+r_area;
return Self_Adjusted_Simpson_Integral(l,mid,l_area)+Self_Adjusted_Simpson_Integral(mid,r,r_area);
}
ld Distance(const Point &p1,const Point &p2)
{
return sqrt( (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y) );
}
void Read()
{
static bool del[M];
int i,j,tot=0;
for(i=1;i<=n;i++)
circles[i].Read();
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
if(circles[j].r-circles[i].r>=Distance(circles[i],circles[j]) )
{
del[i]=1;
break;
}
for(i=1;i<=n;i++)
if(!del[i])
circles[++tot]=circles[i];
n=tot;
}
int main()
{
static Interval intervals[M];
int i,tot=0;
cin>>n;
Read();
for(i=1;i<=n;i++)
intervals[++tot]=Interval(circles[i].x-circles[i].r,circles[i].x+circles[i].r);
sort(intervals+1,intervals+tot+1);
ld temp=-1e5;
for(i=1;i<=tot;i++)
{
if(intervals[i].r<=temp)
continue;
ld l=max(intervals[i].l,temp);
ans+=Self_Adjusted_Simpson_Integral(l,intervals[i].r,Simpson_Integral(l,intervals[i].r));
temp=intervals[i].r;
}
cout<<fixed<<setprecision(3)<<ans<<endl;
return 0;
}