【POJ 1279】Art Gallery
http://poj.org/problem?id=1279
裸的半平面交的模板,按极角排序后维护一个双端队列,不要忘了最后要去除冗余,即最后一条边(或者更多的边)一定在双端队列里,但它不一定构成半平面,所以要特判。
还有平行的边也要特判,因为平行的边的交点不可求!
最后在poj上用G++交WA了好几次,换用C++就AC了/(ㄒoㄒ)/~~
#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const double Pi = acos(-1.0); const int N = 1503; int in() { int k = 0, fh = 1; char c = getchar(); for(; c < '0' || c > '9'; c = getchar()) if (c == '-') fh = -1; for(; c >= '0' && c <= '9'; c = getchar()) k = (k << 3) + (k << 1) + c - '0'; return k * fh; } struct Point { double x, y; Point(double _x = 0, double _y = 0) : x(_x), y(_y) {} } t[N], p[N]; struct Line { Point p, v; double ang; Line(Point _p = Point(0, 0), Point _v = Point(0, 0), double _ang = 0) : p(_p), v(_v), ang(_ang) {} bool operator < (const Line &x) const { return ang < x.ang; } } l[N], q[N]; 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 x) {return Point(a.x * x, a.y * x);} Point operator / (Point a, double x) {return Point(a.x / x, a.y / x);} double dcmp(double x) {return fabs(x) < 1e-8 ? 0 : (x < 0 ? -1 : 1);} double Dot(Point a, Point b) {return a.x * b.x + a.y * b.y;} double Cross(Point a, Point b) {return a.x * b.y - a.y * b.x;} double sqr(double x) {return x * x;} double dis(Point a, Point b) {return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));} bool onleft(Point a, Line b) {return dcmp(Cross(a - b.p, b.v)) < 0;} Point intersection(Line a, Line b) { Point u; double t; u = a.p - b.p; t = Cross(b.v, u) / Cross(a.v, b.v); return a.p + a.v * t; } int n; double mkhalf() { q[1] = l[1]; q[2] = l[2]; p[1] = intersection(q[1], q[2]); int head = 1, tail = 2; for(int i = 3; i <= n; ++i) { while (head < tail && !onleft(p[tail - 1], l[i])) --tail; while (head < tail && !onleft(p[head], l[i])) ++head; q[++tail] = l[i]; if (dcmp(Cross(q[tail].v, q[tail - 1].v)) == 0) { --tail; if (onleft(l[i].p, q[tail])) q[tail] = l[i]; } if (head < tail) p[tail - 1] = intersection(q[tail - 1], q[tail]); } while (head < tail && !onleft(p[tail - 1], q[head])) --tail; p[tail] = intersection(q[head], q[tail]); if (tail - head <= 1) return 0; else { double ret = 0; p[tail + 1] = p[head]; for(int i = head; i <= tail; ++i) ret += Cross(p[i], p[i + 1]); return ret / 2; } } int main() { int T = in(); while (T--) { n = in(); for(int i = 1; i <= n; ++i) scanf("%lf%lf", &t[i].x, &t[i].y); t[n + 1] = t[1]; for(int i = 1; i <= n; ++i) l[i] = Line(t[i + 1], t[i] - t[i + 1], atan2(t[i].y - t[i + 1].y, t[i].x - t[i + 1].x)); sort(l + 1, l + n + 1); printf("%.2lf\n", mkhalf()); } return 0; }
_(:з」∠)_
NOI 2017 Bless All