• poj 3335 Rotating Scoreboard (Half Plane Intersection)


    3335 -- Rotating Scoreboard

      给出一个多边形,要求判断它的内核是否存在。

      还是半平面交的题,在这道题中,公告板允许其所在位置与直线共线也算是可见,于是我们就可以将每一条直线微小的移动,然后判断是够能够交出多边形,这样做是因为对于半平面交是不能直接判断是够交集是一个点的情况的。

    代码如下:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <vector>
      6 #include <cmath>
      7 
      8 using namespace std;
      9 
     10 struct Point {
     11     double x, y;
     12     Point() {}
     13     Point(double x, double y) : x(x), y(y) {}
     14 } ;
     15 template<class T> T sqr(T x) { return x * x;}
     16 typedef Point Vec;
     17 Vec operator + (Vec a, Vec b) { return Vec(a.x + b.x, a.y + b.y);}
     18 Vec operator - (Vec a, Vec b) { return Vec(a.x - b.x, a.y - b.y);}
     19 Vec operator * (Vec a, double p) { return Vec(a.x * p, a.y * p);}
     20 Vec operator / (Vec a, double p) { return Vec(a.x / p, a.y / p);}
     21 
     22 const double EPS = 1e-8;
     23 const double PI = acos(-1.0);
     24 inline int sgn(double x) { return (x > EPS) - (x < -EPS);}
     25 
     26 inline double dotDet(Vec a, Vec b) { return a.x * b.x + a.y * b.y;}
     27 inline double crossDet(Vec a, Vec b) { return a.x * b.y - a.y * b.x;}
     28 inline double dotDet(Point o, Point a, Point b) { return dotDet(a - o, b - o);}
     29 inline double crossDet(Point o, Point a, Point b) { return crossDet(a - o, b - o);}
     30 inline double vecLen(Vec x) { return sqrt(dotDet(x, x));}
     31 inline double toRad(double deg) { return deg / 180.0 * PI;}
     32 inline double angle(Vec v) { return atan2(v.y, v.x);}
     33 inline Vec vecUnit(Vec x) { return x / vecLen(x);}
     34 inline Vec normal(Vec x) { return Vec(-x.y, x.x) / vecLen(x);}
     35 
     36 const int N = 111;
     37 struct DLine {
     38     Point p;
     39     Vec v;
     40     double ang;
     41     DLine() {}
     42     DLine(Point p, Vec v) : p(p), v(v) { ang = atan2(v.y, v.x);}
     43     bool operator < (DLine L) const { return ang < L.ang;}
     44     DLine move(double x) {
     45         Vec nor = normal(v);
     46         nor = nor * x;
     47         return DLine(p + nor, v);
     48     }
     49 } dl[N];
     50 Point pt[N];
     51 
     52 inline bool onLeft(DLine L, Point p) { return crossDet(L.v, p - L.p) > 0;}
     53 Point dLineIntersect(DLine a, DLine b) {
     54     Vec u = a.p - b.p;
     55     double t = crossDet(b.v, u) / crossDet(a.v, b.v);
     56     return a.p + a.v * t;
     57 }
     58 
     59 struct Poly {
     60     vector<Point> pt;
     61     Poly() { pt.clear();}
     62     ~Poly() {}
     63     Poly(vector<Point> &pt) : pt(pt) {}
     64     Point operator [] (int x) { return pt[x];}
     65     int size() { return pt.size();}
     66     double area() {
     67         double ret = 0.0;
     68         int sz = pt.size();
     69         pt.push_back(pt[0]);
     70         for (int i = 1; i <= sz; i++) ret += crossDet(pt[i], pt[i - 1]);
     71         pt.pop_back();
     72         return fabs(ret / 2.0);
     73     }
     74 } ;
     75 
     76 Poly halfPlane(DLine *L, int n) {
     77     Poly ret = Poly();
     78     sort(L, L + n);
     79     int fi, la;
     80     Point *p = new Point[n];
     81     DLine *q = new DLine[n];
     82     q[fi = la = 0] = L[0];
     83     for (int i = 1; i < n; i++) {
     84         while (fi < la && !onLeft(L[i], p[la - 1])) la--;
     85         while (fi < la && !onLeft(L[i], p[fi])) fi++;
     86         q[++la] = L[i];
     87         if (sgn(crossDet(q[la].v, q[la - 1].v)) == 0) {
     88             la--;
     89             if (onLeft(q[la], L[i].p)) q[la] = L[i];
     90         }
     91         if (fi < la) p[la - 1] = dLineIntersect(q[la - 1], q[la]);
     92     }
     93     while (fi < la && !onLeft(q[fi], p[la - 1])) la--;
     94     if (la <= fi) return ret;
     95     p[la] = dLineIntersect(q[la], q[fi]);
     96     for (int i = fi; i <= la; i++) ret.pt.push_back(p[i]);
     97     return ret;
     98 }
     99 
    100 bool isClockwise(Point *pt, int n) {
    101     double sum = 0.0;
    102     pt[n] = pt[0];
    103     Point O = Point(0.0, 0.0);
    104     for (int i = 0; i < n; i++) {
    105         sum += crossDet(O, pt[i], pt[i + 1]);
    106     }
    107     return sum < 0;
    108 }
    109 
    110 int main() {
    111 //    freopen("in", "r", stdin);
    112     int T, n;
    113     cin >> T;
    114     while (T-- && cin >> n) {
    115         for (int i = 0; i < n; i++) cin >> pt[i].x >> pt[i].y;
    116         pt[n] = pt[0];
    117         if (isClockwise(pt, n)) for (int i = 0; i < n; i++) dl[i] = DLine(pt[i + 1], pt[i] - pt[i + 1]).move(-EPS);
    118         else for (int i = 0; i < n; i++) dl[i] = DLine(pt[i], pt[i + 1] - pt[i]).move(-EPS);
    119         Poly tmp = halfPlane(dl, n);
    120         if (tmp.size() > 2) puts("YES");
    121         else puts("NO");
    122     }
    123     return 0;
    124 }
    125 
    126 /*
    127 3
    128 6
    129 0 0
    130 100 0
    131 100 100
    132 0 100
    133 50 75
    134 50 25
    135 4
    136 0 0
    137 0 1
    138 1 1
    139 1 0
    140 8
    141 0 0
    142 0 2
    143 1 2
    144 1 1
    145 2 1
    146 2 2
    147 3 2
    148 3 0
    149 */
    View Code

    ——written by Lyon

  • 相关阅读:
    个推微服务网关架构实践
    NB-IoT 的“前世今生”
    个推基于Consul的配置管理
    个推Node.js 微服务实践:基于容器的一站式命令行工具链
    个推用户画像的实践与应用
    TensorFlow分布式实践
    个数是如何用大数据做行为预测的?
    QCon技术干货:个推基于Docker和Kubernetes的微服务实践
    基于CMS的组件复用实践
    数据可视化:浅谈热力图如何在前端实现
  • 原文地址:https://www.cnblogs.com/LyonLys/p/poj_3335_Lyon.html
Copyright © 2020-2023  润新知