题目大意:给定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; }
时间: 2024-11-14 14:33:50