链接: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 }
