记录编号 147307 评测结果 AAAAAAAAAA
题目名称 1313.[HAOI 2008]下落的圆盘 最终得分 100
用户昵称 天一阁 是否通过 通过
代码语言 C++ 运行时间 0.121 s
提交时间 2015-01-29 07:08:00 内存使用 0.34 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#define Maxn 1010
#define LD double
#define pi 3.14159265358
using namespace std;
struct node{
	LD x,y,r;
	void scan(){
		scanf("%lf%lf%lf",&r,&x,&y);
	}
}C[Maxn];
struct sege{LD l,r;};
int n;
LD ans=0;
vector<sege> V;
bool operator<(sege a,sege b){
	return a.l<b.l;
}
LD dist(node a,node b){
	return (LD)sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool cover(node a,node b){
	if(a.r>=b.r+dist(a,b)) return true;
	return false;
}
void insert(node a,node b){
	LD d=dist(a,b);
	LD tmp=(a.r*a.r-b.r*b.r+d*d)/(2*d);
	LD l=atan2(a.x-b.x,a.y-b.y),len=acos(tmp/a.r);
	V.push_back((sege){l-len,l+len});
}
LD solve(int x){
	for(int i=x+1;i<=n;i++) if(cover(C[i],C[x])) return 0;
	V.clear();
	for(int i=x+1;i<=n;i++){
		if(!cover(C[x],C[i])&&C[x].r+C[i].r>=dist(C[x],C[i])){
			insert(C[x],C[i]);
		}
	}
	for(int i=0;i<V.size();i++){
		if(V[i].l<0) V[i].l+=2*pi;
		if(V[i].r<0) V[i].r+=2*pi;
		if(V[i].l>V[i].r) V.push_back((sege){0,V[i].r}),V[i].r=2*pi;
	}
	LD res=0,now=0;
	sort(V.begin(),V.end());
	for(int i=0;i<V.size();i++){
		if(V[i].l<=now) now=max(now,V[i].r);
		else res+=V[i].l-now,now=V[i].r;
	}
	res+=2*pi-now;
	return C[x].r*res;
}
int main(){
	freopen("disc.in","r",stdin);
	freopen("disc.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++) C[i].scan();
	for(int i=1;i<=n;i++) ans+=solve(i);
	printf("%.3lf\n",ans);
	return 0;
}