BZOJ1043 [HAOI2008]下落的圆盘

来源:互联网 发布:php 自动化部署工具 编辑:程序博客网 时间:2024/03/28 20:41

每个圆盘只会受到后边的圆盘的影响

所以算一下每个圆盘和后边的圆盘相交的圆心角,然后求个并即可

可以用余弦定理

复杂度n^2 log n

注意特判没有交-_-

#include<iostream>#include<cstring>#include<ctime>#include<cmath>#include<algorithm>#include<iomanip>#include<cstdlib>#include<cstdio>#include<map>#include<bitset>#include<set>#include<stack>#include<vector>#include<queue>using namespace std;#define MAXN 1010#define MAXM 1010#define ll long long#define eps 1e-8#define MOD 1000000007#define INF 1000000000const double pi=acos(-1);struct cir{double x;double y;double r;};struct itv{double l;double r;itv(){}itv(double _l,double _r){l=_l;r=_r;}friend bool operator <(itv x,itv y){return x.l<y.l;}};itv a[MAXN*2];cir c[MAXN];double ans;int tot;int n;double sq(double x){return x*x;}double dis(cir x,cir y){return sqrt(sq(x.x-y.x)+sq(x.y-y.y));}double cal(){int i;double re=0;sort(a+1,a+tot+1);double r=-pi;for(i=1;i<=tot;i++){if(a[i].l>r){re+=a[i].l-r;}r=max(r,a[i].r);}re+=pi-r;return re;}int main(){int i,j;scanf("%d",&n);for(i=1;i<=n;i++){scanf("%lf%lf%lf",&c[i].r,&c[i].x,&c[i].y);}for(i=n;i;i--){bool flag=0;tot=0;for(j=i+1;j<=n;j++){if(dis(c[i],c[j])<c[i].r+c[j].r){if(dis(c[i],c[j])+c[i].r<=c[j].r){flag=1;break;}else if(dis(c[i],c[j])+c[j].r<=c[i].r){}else{double angf=acos((sq(c[i].r)+sq(dis(c[i],c[j]))-sq(c[j].r))/(2*c[i].r*dis(c[i],c[j])));double ang=atan2(c[j].y-c[i].y,c[j].x-c[i].x);double l=ang-angf,r=ang+angf;if(l<-pi){a[++tot]=itv(l+2*pi,pi);a[++tot]=itv(-pi,r);}else if(r>pi){a[++tot]=itv(l,pi);a[++tot]=itv(-pi,r-2*pi);}else{a[++tot]=itv(l,r);}}}}if(flag){continue ;}ans+=cal()*c[i].r;}printf("%.3lf\n",ans);return 0;}/**/


0 0
原创粉丝点击