poj 1474 Video Surveillance (半平面交)

1474 -- Video Surveillance

  跟前一篇3335的是一样的。

代码入下:

  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 = 1, n;
113     while (cin >> n && n) {
114         for (int i = 0; i < n; i++) cin >> pt[i].x >> pt[i].y;
115         pt[n] = pt[0];
116         if (isClockwise(pt, n)) for (int i = 0; i < n; i++) dl[i] = DLine(pt[i + 1], pt[i] - pt[i + 1]).move(-EPS);
117         else for (int i = 0; i < n; i++) dl[i] = DLine(pt[i], pt[i + 1] - pt[i]).move(-EPS);
118         Poly tmp = halfPlane(dl, n);
119         printf("Floor #%d
Surveillance is ", T++);
120         if (tmp.size() > 2) puts("possible.");
121         else puts("impossible.");
122         puts("");
123     }
124     return 0;
125 }
126 
127 /*
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

原文地址:https://www.cnblogs.com/LyonLys/p/poj_1474_Lyon.html