记录编号 |
378616 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[HAOI 2008]下落的圆盘 |
最终得分 |
100 |
用户昵称 |
天一阁 |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.313 s |
提交时间 |
2017-03-04 11:50:45 |
内存使用 |
0.37 MiB |
显示代码纯文本
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>
#define LD double
#define sqr(x) ((x)*(x))
#define eps 1e-8
#define INF 1e50
#define N 1010
#define PI acos(-1)
using namespace std;
/*
+:向量+
-:向量-
*:向量的数乘 ,点积
^: 向量的叉积
*/
struct node
{
LD x,y;
void scan()
{
scanf("%lf%lf",&x,&y);
}
void print()
{
printf("(%lf,%lf)\n",x,y);
}
node operator+(const node &a)const
{
return (node){x+a.x,y+a.y};
}
node operator-(const node &a)const
{
return (node){x-a.x,y-a.y};
}
node operator*(const LD &a)const
{
return (node){x*a,y*a};
}
node operator/(const LD &a)const
{
return (node){x/a,y/a};
}
LD operator^(const node &a)
{
return x*a.y-y*a.x;
}
LD operator*(const node &a)
{
return x*a.x+y*a.y;
}
void operator+=(const node &a)
{
*this=*this+a;
}
void operator-=(const node &a)
{
*this=*this-a;
}
void operator*=(const LD &a)
{
*this=(*this)*a;
}
void operator/=(const LD &a)
{
*this=*this/a;
}
LD len()
{
return (LD)sqrt(sqr(x)+sqr(y));
}
bool operator==(const node &a)const
{
return x==a.x && y==a.y;
}
bool operator<(const node &a)const
{
if(x==a.x) return y<a.y;
return x<a.x;
}
};
LD dist(node a,node b)
{
return (a-b).len();
}
struct line
{
node a,b;
LD len()
{
return (a-b).len();
}
void scan()
{
a.scan();
b.scan();
}
void print()
{
puts("the Line is");
a.print();
b.print();
}
};
node unit(node x)
{
LD tmp=x.len();
x/=tmp;
return x;
}
struct circle
{
node o;
LD r;
void print()
{
o.print();
printf("r = %.3lf\n",r);
}
}a[N];
int n;
LD poly_ans;
bool cmp(circle a,circle b)
{
if(a.o==b.o) return a.r<b.r;
return a.o<b.o;
}
node rot(node tmp,LD A) //逆时针将x向量转过angle°角
{
return (node){ tmp.x*cos(A)-tmp.y*sin(A),
tmp.x*sin(A)+tmp.y*cos(A)};
}
LD calc_S(LD A,LD r)
{
return A*r;
// return 0.5*sqr(r)*(A-sin(A));
}
LD calc_poly(node a,node b)
{
return a^b * 0.5;
}
struct sege
{
LD l,r;
}b[N<<1];
bool cmp1(sege a,sege b)
{
return a.l < b.l;
}
LD calc(int x)
{
LD ans=0;
node p1 = a[x].o,p2;
LD r1=a[x].r,r2;
int cnt=0;
for(int i=x+1;i<=n;i++)
{
p2=a[i].o, r2=a[i].r;
LD d = dist(p1,p2);
if(d >= r1+r2) continue;
if(r1+d<=r2) return 0;
if(r2+d<=r1) continue;
LD len1 = (sqr(r1)-sqr(r2)+sqr(d))/(2*d);
LD angle1 = acos(len1/r1);
node v0 = (p2-p1)/d*r1;
node x1 = rot(v0,-angle1);
node x2 = rot(v0,angle1);
//
poly_ans += calc_poly(x1,a[x].o);
poly_ans += calc_poly(a[x].o,x2);
//
// a[x].print();
// a[i].print();
// puts("cross");
LD l = atan2(x1.y,x1.x);
LD r = atan2(x2.y,x2.x);
// cout << l << ' ' << r << endl;
if(l<0) l+=2*PI;
if(r<0) r+=2*PI;
if(l>r)
{
b[++cnt] = (sege){0.0,r};
b[++cnt] = (sege){l,2*PI};
}
else b[++cnt] = (sege){l,r};
}
LD R=0;
if(!cnt) return calc_S(2*PI,r1);
sort(b+1,b+cnt+1,cmp1);
R=b[1].r;
for(int i=2;i<=cnt;i++)
{
if(b[i].l>R)
{
ans+=calc_S(b[i].l-R,r1);
R=b[i].r;
}
else R=max(R,b[i].r);
}
ans+=calc_S(b[1].l-R+2*PI,r1);
return ans;
}
int main()
{
// freopen("test.txt","r",stdin);
freopen("disc.in", "r",stdin);
freopen("disc.out","w",stdout);
while(~scanf("%d",&n))
{
LD ans=0;
poly_ans=0;
for(int i=1;i<=n;i++)
scanf("%lf%lf%lf",&a[i].r,&a[i].o.x,&a[i].o.y);
// sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++) ans += calc(i);
printf("%.3lf\n", ans/*+poly_ans*/);
}
return 0;
}