poj 3335 Rotating Scoreboard(判断多边形是否有核+半平面交)

来源:互联网 发布:淘宝网男真皮登山背包 编辑:程序博客网 时间:2024/04/27 21:06

【题目大意】:顺时针给出n个点,判断多边形是否有核。


【解题思路】:半平面交模版测试


【代码】:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>#include <cmath>#include <string>#include <cctype>#include <map>#include <iomanip>                   using namespace std;                   #define eps 1e-8#define pi acos(-1.0)#define inf 1<<30#define linf 1LL<<60#define pb push_back#define lc(x) (x << 1)#define rc(x) (x << 1 | 1)#define lowbit(x) (x & (-x))#define ll long long#define MAXN 150struct Point {    double x,y;    Point() {}    Point(double _x,double _y){        x=_x,y=_y;    }};/*半平面相交(直线切割多边形)(点标号从1开始)*/  Point points[MAXN],p[MAXN],q[MAXN];  int n;  double r;  int cCnt,curCnt;  int sig(double k){    return (k<-eps)?-1:(k>eps);}inline void getline(Point x,Point y,double &a,double &b,double &c){      a=y.y-x.y;      b=x.x-y.x;      c=y.x*x.y-x.x*y.y;  }  inline void initial(){      for (int i=1; i<=n; ++i) p[i]=points[i];      p[n+1]=p[1];      p[0]=p[n];      cCnt=n;  }  inline Point intersect(Point x,Point y,double a,double b,double c){      double u=fabs(a*x.x+b*x.y+c);      double v=fabs(a*y.x+b*y.y+c);      return Point((x.x*v+y.x*u)/(u+v),(x.y*v+y.y*u)/(u+v));  }  inline void cut(double a,double b ,double c){      curCnt=0;      for (int i=1; i<=cCnt; ++i){          if (sig(a*p[i].x+b*p[i].y+c)>=0) q[++curCnt]=p[i];          else {              if (sig(a*p[i-1].x+b*p[i-1].y+c)>0){                  q[++curCnt]=intersect(p[i],p[i-1],a,b,c);              }              if(sig(a*p[i+1].x+b*p[i+1].y+c)>0){                  q[++curCnt]=intersect(p[i],p[i+1],a,b,c);              }          }      }      for (int i=1; i<=curCnt; ++i) p[i]=q[i];      p[curCnt+1]=p[1];    p[0]=p[curCnt];      cCnt=curCnt;    return ;  }  inline void solve(){      //注意:默认点是顺时针,如果题目不是顺时针,规整化方向      initial();     for(int i=1; i<=n; ++i){          double a,b,c;          getline(points[i],points[i+1],a,b,c);          cut(a,b,c);      }      if (!cCnt) cout << "NO" << endl;    else cout << "YES" << endl;    //此时cCnt为最终切割得到的多边形的顶点数,p为存放顶点的数组  }inline void GuiZhengHua(){      //规整化方向,逆时针变顺时针,顺时针变逆时针      for(int i = 1; i < (n+1)/2; i ++)        swap(points[i], points[n-i]);//头文件加iostream  } int main() {    int T;    cin >> T;    while (T--){        scanf("%d",&n);        double a,b;        for (int i=1; i<=n; i++){            scanf("%lf%lf",&a,&b);            points[i]=Point(a,b);        }        points[n+1]=points[1];        //  GuiZhengHua();        solve();    }    return 0;}