记录编号 385163 评测结果 AAAAAAAAAA
题目名称 [HAOI 2008]下落的圆盘 最终得分 100
用户昵称 Gravatar再见 是否通过 通过
代码语言 C++ 运行时间 0.187 s
提交时间 2017-03-20 13:30:36 内存使用 0.34 MiB
显示代码纯文本
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define Pi 3.1415926535
#define EPS 0.000001

using std::sort;

int n,cnt,flag;
double x[1010],y[1010],r[1010],ans;
double ax[2],ay[2],t;

struct node{ double l,r; }A[2010];
bool cmp(const node &a,const node &b){
	return a.l<b.l;}

inline double xmax(double a,double b){
	return a>b?a:b;
}

inline double tpdis(double x1,double y1,double x2,double y2){
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

inline double xabs(double x){
	return x<0?-x:x;
}

inline double solve(double a,double b,double c){
	double del=sqrt(b*b-4*a*c);
	ax[0]=(-b+del)/2/a; ax[1]=(-b-del)/2/a;
}

inline double get(double x,double y){
	if(x>-EPS&&x<EPS&&y>0) return Pi/2;
	if(x>-EPS&&x<EPS&&y<0) return -Pi/2;
	if(x>0&&y>0) return atan(y/x);
	if(x<0&&y>0) return Pi-atan(-y/x);
	if(x<0&&y<0) return Pi+atan(y/x);
	if(x>0&&y<0) return Pi+Pi-atan(-y/x);
}

inline void add(double ll,double rr){
	++cnt; A[cnt].l=ll; A[cnt].r=rr;
}

void work(){
	for(int i=1;i<=n;i++){
		cnt=0; flag=false;
		for(int j=i+1;j<=n;j++){
			double rdis=tpdis(x[i],y[i],x[j],y[j]);
			if(rdis+r[j]<=r[i]||rdis>=r[i]+r[j]) continue;
			if(rdis+r[i]<=r[j]) {flag=true; break; }
			double A=2*(x[j]-x[i]),B=2*(y[j]-y[i]),
				 C=x[i]*x[i]-x[j]*x[j]+y[i]*y[i]-y[j]*y[j]+r[j]*r[j]-r[i]*r[i];
			//printf("%lf %lf %lf ",A,B,C);
			if(B>-EPS&&B<EPS){
				ax[0]=ax[1]=-C/A;
				ay[0]=sqrt(r[i]*r[i]-(ax[0]-x[i])*(ax[0]-x[i]))+y[i];
				ay[1]=2*y[i]-ay[0];
			}
			else{
				solve(1+A*A/B/B,-2*x[i]+2*A*C/B/B+2*A*y[i]/B,x[i]*x[i]+y[i]*y[i]+C*C/B/B+2*C*y[i]/B-r[i]*r[i]);
				ay[0]=(-A*ax[0]-C)/B; ay[1]=(-A*ax[1]-C)/B;
			}
			//printf("x=%lf y=%lf ",ax[0],ay[0]);
			//printf("x=%lf y=%lf ",ax[1],ay[1]);
			double deg1=get(ax[0]-x[i],ay[0]-y[i]),deg2=get(ax[1]-x[i],ay[1]-y[i]);
			if(deg1>deg2) t=deg1,deg1=deg2,deg2=t;
			if(r[i]*r[i]+rdis*rdis>r[j]*r[j]){
				if(deg2-deg1>Pi) add(0,deg1),add(deg2,Pi+Pi);
				else add(deg1,deg2);
			}
			else{
				if(deg2-deg1>Pi) add(deg1,deg2);
				else add(0,deg1),add(deg2,Pi+Pi);
			}
		}
		if(!flag){
			double len=0,nowl=0,nowr=0;
			if(cnt>=1) sort(A+1,A+cnt+1,cmp);
			for(int j=1;j<=cnt;j++){
				if(A[j].l<nowr) nowr=xmax(nowr,A[j].r);
				else len+=nowr-nowl,nowl=A[j].l,nowr=A[j].r;
			}
			len+=nowr-nowl;
			ans+=r[i]*(2*Pi-len);
		}
	}
}

int main(){
	freopen("disc.in","r",stdin);
	freopen("disc.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%lf%lf%lf",&r[i],&x[i],&y[i]);
	ans=0; work();
	printf("%.3lf\n",ans);
	return 0;
}