-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy path1043 [HAOI2008]下落的圆盘(计算几何圆求交).cpp
75 lines (75 loc) · 1.45 KB
/
1043 [HAOI2008]下落的圆盘(计算几何圆求交).cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int N=1005;
int n;
typedef double db;
const db eps=1e-7,pi=acos(-1);
inline db sqr(const db x){
return x*x;
}
struct vec{
db x,y;
vec(db _x=0,db _y=0):x(_x),y(_y){
}
};
struct circle:vec{
db r;
} a[N];
typedef pair<db,int> data;
data ord[N*4],*top;
db ans;
int main(){
freopen("1043.in","r",stdin);
freopen("1043.out","w",stdout);
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%lf%lf%lf",&a[i].r,&a[i].x,&a[i].y);
for(circle *u=a;u<a+n;u++){
top=ord;
for(circle *v=u+1;v<a+n;v++){
vec t(v->x-u->x,v->y-u->y);
db dis2=sqr(t.x)+sqr(t.y);
if(sqrt(dis2)+u->r<=v->r+eps){
top=ord;
*top++=data(-pi,1);
*top++=data(pi,-1);
break;
}
if(sqr(u->r+v->r)<=dis2+eps||sqrt(dis2)+v->r<=u->r+eps) continue;
db dir=atan2(t.y,t.x),
theta=acos((dis2+sqr(u->r)-sqr(v->r))/(2*sqrt(dis2)*u->r)),
l=dir-theta,
r=dir+theta;
if(l<-pi){
*top++=data(l+2*pi,1);
*top++=data(pi,-1);
*top++=data(-pi,1);
*top++=data(r,-1);
}
else
if(r>pi){
*top++=data(l,1);
*top++=data(pi,-1);
*top++=data(-pi,1);
*top++=data(r-2*pi,-1);
}
else{
*top++=data(l,1);
*top++=data(r,-1);
}
}
*top++=data(-pi,0);
*top++=data(pi,0);
sort(ord,top);
int cov=0;
db now=0;
for(data *p=ord;p+1<top;p++){
cov+=p[0].second;
if(!cov) now+=p[1].first-p[0].first;
}
ans+=now*u->r;
}
printf("%.3lf\n",ans);
scanf("\n");
}