继续半平面交,这还是简单的半平面交求面积,不过输入用cin超时了一次。
代码如下:
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 = 22222; 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 } dl[N]; 45 46 inline bool onLeft(DLine L, Point p) { return crossDet(L.v, p - L.p) > 0;} 47 Point dLineIntersect(DLine a, DLine b) { 48 Vec u = a.p - b.p; 49 double t = crossDet(b.v, u) / crossDet(a.v, b.v); 50 return a.p + a.v * t; 51 } 52 53 struct Poly { 54 vector<Point> pt; 55 Poly() { pt.clear();} 56 ~Poly() {} 57 Poly(vector<Point> &pt) : pt(pt) {} 58 Point operator [] (int x) { return pt[x];} 59 int size() { return pt.size();} 60 double area() { 61 double ret = 0.0; 62 int sz = pt.size(); 63 pt.push_back(pt[0]); 64 for (int i = 1; i <= sz; i++) ret += crossDet(pt[i], pt[i - 1]); 65 pt.pop_back(); 66 return fabs(ret / 2.0); 67 } 68 } ; 69 70 Poly halfPlane(DLine *L, int n) { 71 Poly ret = Poly(); 72 sort(L, L + n); 73 int fi, la; 74 Point *p = new Point[n]; 75 DLine *q = new DLine[n]; 76 q[fi = la = 0] = L[0]; 77 for (int i = 1; i < n; i++) { 78 while (fi < la && !onLeft(L[i], p[la - 1])) la--; 79 while (fi < la && !onLeft(L[i], p[fi])) fi++; 80 q[++la] = L[i]; 81 if (sgn(crossDet(q[la].v, q[la - 1].v)) == 0) { 82 la--; 83 if (onLeft(q[la], L[i].p)) q[la] = L[i]; 84 } 85 if (fi < la) p[la - 1] = dLineIntersect(q[la - 1], q[la]); 86 } 87 while (fi < la && !onLeft(q[fi], p[la - 1])) la--; 88 if (la < fi) return ret; 89 p[la] = dLineIntersect(q[la], q[fi]); 90 for (int i = fi; i <= la; i++) ret.pt.push_back(p[i]); 91 return ret; 92 } 93 94 const int dir[4][2] = { {0, 0}, {1, 0}, {1, 1}, {0, 1}}; 95 96 int main() { 97 int T, n; 98 while (~scanf("%d", &n)) { 99 Point x[2]; 100 for (int i = 0; i < n; i++) { 101 for (int j = 0; j < 2; j++) { 102 scanf("%lf%lf", &x[j].x, &x[j].y); 103 } 104 dl[i] = DLine(x[0], x[1] - x[0]); 105 } 106 for (int i = 0; i < 4; i++) { 107 dl[n + i] = DLine(Point(10000.0 * dir[i][0], 10000.0 * dir[i][1]), 108 Point(10000.0 * dir[(i + 1) & 3][0], 10000.0 * dir[(i + 1) & 3][1]) - Point(10000.0 * dir[i][0], 10000.0 * dir[i][1])); 109 } 110 Poly tmp = halfPlane(dl, n + 4); 111 printf("%.1f\n", tmp.area()); 112 } 113 return 0; 114 }
——written by Lyon