【BZOJ】【POI2007】【对称轴osi】【题解】【计算几何】

来源:互联网 发布:ebsco 数据库 编辑:程序博客网 时间:2024/04/30 02:59

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1100

vfk是厉害http://vfleaking.blog.163.com/blog/static/17480763420123183831110/

我觉得这种做法随便卡……

Code:

#include<bits/stdc++.h>using namespace std;const double eps=1e-7;const double pi=acos(-1);#define prev(i) ((i)-1>=0?(i)-1:(n<<1)-1)#define next(i) ((i)+1<(n<<1)?(i)+1:0)const int maxn=1e5+5;struct Point{double x,y;Point(double _x=0,double _y=0):x(_x),y(_y){}}p[maxn<<1];typedef Point Vector;Point operator+(Point a,Point b){return Point(a.x+b.x,a.y+b.y);}Point operator-(Point a,Point b){return Point(a.x-b.x,a.y-b.y);}Point operator*(Point a,double p){return Point(a.x*p,a.y*p);}int dcmp(double x){if(fabs(x)<eps)return 0;return x>0?1:-1;} bool operator==(Vector A,Vector B){return !dcmp(A.x-B.x)&&!dcmp(A.y-B.y);}  bool operator!=(Vector A,Vector B){return !(A==B);}  double sqr(double x){return x*x;}double Length(Vector a){return sqrt(sqr(a.x)+sqr(a.y));}double Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}double Angle(Vector a,Vector b){return acos(Dot(a,b)/Length(a)/Length(b));}Vector Normal(Vector a){double Len=Length(a);return Vector(-a.y/Len,a.x/Len);}  double Cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;}  struct Line{      Point p;Vector v;      Line(Point _p=Point(0,0),Vector _v=Vector(0,0)):          p(_p),v(_v){}  }L[2];double Distance(Point P,Line L){      Point A=L.p,B=L.p+L.v;      Vector u=P-A,v=B-A;      return fabs(Cross(u,v))/Length(v);  }   int _,n;bool can(int a,int b){int l=prev(a);int r=next(a);Line L=Line(p[a],p[b]-p[a]);Vector v=Normal(L.v);while(l!=r){double dl=Distance(p[l],L);if(p[l]+v*2*dl!=p[r]&&p[l]-v*2*dl!=p[r])return false;l=prev(l);r=next(r);}return true;}int main(){scanf("%d",&_);while(_--){scanf("%d",&n);int len=0;for(int i=0;i<n;i++)scanf("%lf%lf",&p[i<<1].x,&p[i<<1].y);for(int i=0;i<n;i++)p[i<<1|1]=(p[prev(i<<1|1)]+p[next(i<<1|1)])*0.5;for(int i=0;i<n;i++){if(can(i,(i+n)%(n<<1)))L[len++]=(Line){p[i],p[(i+n)%(n<<1)]-p[i]};if(len==2)break;}double rad=Angle(L[0].v,L[1].v);if(len==0)puts("0");else if(len==1)puts("1");else printf("%d\n",int(pi/rad+.5));}return 0;}


0 0
原创粉丝点击