链接:https://vjudge.net/problem/SPOJ-CIRU
辛普森积分:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N = 1000+9; 4 #define eps 1e-6 5 #define inf 0x3f3f3f3f 6 struct Cir{ 7 double x,y,r; 8 }c[N],tmp[N]; 9 pair<double,double> seg[N]; 10 bool cmp2(Cir a,Cir b){return a.r > b.r;} 11 bool cmp(Cir a,Cir b){ 12 return (fabs(a.x - a.r - b.x + b.r ) < eps) ? a.x + a.r < b.x + b.r : a.x - a.r < b.x - b.r; 13 } 14 bool in_cir(Cir a,Cir b){ 15 return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) <= (a.r -b.r) * (a.r - b.r); 16 } 17 int n,st,ed; 18 void prework(){ 19 sort(c+1,c+1+n,cmp2); 20 int cnt = 0; 21 for(int i = 1;i<=n;++i){ 22 bool ok = 1; 23 for(int j = 1;j<=cnt;++j){ 24 if(in_cir(c[i],c[j])){ 25 ok = 0; 26 break; 27 } 28 } 29 if(ok) tmp[++cnt] = c[i]; 30 } 31 n = cnt; 32 memcpy(c,tmp,sizeof(tmp)); 33 } 34 double getf(double x){ 35 int tot = 0; 36 for(int i = st;i<=ed;++i){ 37 if(x < c[i].x + c[i].r && x > c[i].x - c[i].r){ 38 double len = sqrt(c[i].r * c[i].r - ( x -c[i].x ) * (x - c[i].x) ); 39 seg[++tot] = make_pair(c[i].y-len,c[i].y + len); 40 } 41 } 42 sort(seg+1,seg+1+tot); 43 double ans = 0,segl = -inf ,segr = -inf; 44 for(int i = 1;i<=tot;++i){ 45 if(seg[i].first >= segr){ 46 ans += segr - segl; 47 segl = seg[i].first; 48 segr = seg[i].second; 49 } 50 else segr = max(segr,seg[i].second); 51 } 52 ans += segr - segl; 53 return ans; 54 } 55 double calc(double len,double fL,double fM,double fR){ 56 return (fL + 4*fM + fR) * len / 6; 57 } 58 double Simpson(double L,double M,double R,double fL,double fM,double fR,double sum){ 59 double M1 = (L+M)/2 , M2 = (M+R)/2; 60 double fM1 = getf(M1), fM2 = getf(M2); 61 double g1 = calc(M-L,fL,fM1,fM) , g2 = calc(R-M,fM,fM2,fR); 62 if(fabs(sum - g1 - g2) <= eps ) return g1 + g2; 63 return Simpson(L,M1,M,fL,fM1,fM,g1) + Simpson(M,M2,R,fM,fM2,fR,g2); 64 } 65 void solve(){ 66 sort(c+1,c+1+n,cmp); 67 double ans = 0; 68 for(int i = 1;i<=n;++i){ 69 double L = c[i].x - c[i].r , R = c[i].x + c[i].r; 70 int j; 71 for(j = i+1;j<=n;++j){ 72 if(c[j].x - c[j].r > R) break; 73 else R = max(R,c[j].x + c[j].r); 74 } 75 double M = (L+R)/2; 76 st = i,ed = j-1; 77 i = j-1; 78 double fL = getf(L),fM = getf(M),fR = getf(R); 79 ans += Simpson(L,M,R,fL,fM,fR,calc(R-L,fL,fM,fR)); 80 } 81 printf("%.3f\n",ans); 82 } 83 int main(){ 84 scanf("%d",&n); 85 for(int i = 1;i<=n;++i) scanf("%lf %lf %lf",&c[i].x,&c[i].y,&c[i].r); 86 prework(); 87 solve(); 88 }