標籤:
2178: 圓的面積並Time Limit: 20 Sec Memory Limit: 259 MB
Submit: 1318 Solved: 341
[Submit][Status][Discuss]Description給出N個圓,求其面積並Input先給一個數字N ,N< = 1000 接下來是N行是圓的圓心,半徑,其絕對值均為小於1000的整數Output面積並,保留三位小數
Simpson積分裸題
P.S. 如何解決線段長度並:按左端點排序,然後記錄當前右端點的最大值,掃一遍即可。
#include<iostream>#include<cstdlib>#include<cstring>#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 ll long long#define ull unsigned long long#define ld double#define maxn 1005#define inf 1e9#define eps 1e-7using namespace std;int n,tot;bool tag[maxn];struct circle{ld x,y,r;}a[maxn],b[maxn];struct segment{ld l,r;}p[maxn];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 ld get(ld x){int cnt=0;F(i,1,n) if (fabs(x-a[i].x)<=a[i].r-eps){ld 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);ld h=-inf,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 ld calc(ld l,ld r){ld mid=(l+r)/2;return (get(l)/6+get(mid)*2/3+get(r)/6)*(r-l);}inline ld simpson(ld l,ld r){ld 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;}
bzoj2178 圓的面積並