记录编号 |
385163 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[HAOI 2008]下落的圆盘 |
最终得分 |
100 |
用户昵称 |
再见 |
是否通过 |
通过 |
代码语言 |
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;
}