标签:
传送门:Cool Points
题意:给一个圆心为原点的圆和一些线段,问所有线段两端点与圆心连线构成的角度总和占总360度的百分比。
分析:首先将所有线段的两端点变成极角,然后排序(范围[-PI,PI],即从x轴负方向逆时针转一圈),如果某一线段极角值之差大于PI,构成的角度值肯定不是<AOB,而是<AOX+XOB。因此处理好这种情况,从x轴负向走一圈计值即可。
#include <algorithm> #include <cstdio> #include <cstring> #include <cmath> #define N 1010 #define PI acos(-1.0) using namespace std; struct node { double angle; int num; node(){} node(double angle,int num):angle(angle),num(num){} bool operator<(const node &a)const{ return angle<a.angle; } }e[N]; int tot; void addseg(double x,double y) { e[tot++]=node(x,1); e[tot++]=node(y,-1); } int main() { int T,n,r,cas=1; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&r); tot=0; for(int i=1;i<=n;i++) { double x1,y1,x2,y2; scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); double a1=atan2(y1,x1),a2=atan2(y2,x2); if(a1<a2)swap(a1,a2); if(a1-a2>PI) { addseg(a1,PI); addseg(-PI,a2); } else addseg(a2,a1); } sort(e,e+tot); int cnt=0; double ans=0,last=-PI; for(int i=0;i<tot;i++) { if(cnt==0)//前面的线段刚好成对 { ans+=e[i].angle-last; } cnt+=e[i].num; last=e[i].angle; } ans+=PI-last; printf("Case %d: %.2lf%%\n",cas++,ans/(2*PI)*100); } }
标签:
原文地址:http://www.cnblogs.com/lienus/p/4330618.html