A:Abstract Art
题意:给出n个多边形,求n个多边形分别的面积和,以及面积并
思路:模板
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 1010 5 #define mkp make_pair 6 const double eps = 1e-12; 7 8 inline int sgn(double x) 9 { 10 if (fabs(x) < eps) return 0; 11 if (x < 0) return -1; 12 return 1; 13 } 14 15 struct Point 16 { 17 double x, y; 18 inline Point() {} 19 inline Point(double x, double y) : x(x), y(y) {} 20 inline void scan() { scanf("%lf%lf", &x, &y); } 21 inline bool operator == (const Point &b) const { return sgn(x - b.x) == 0 && sgn(y - b.y) == 0; } 22 inline bool operator < (const Point &b) const { return sgn(x - b.x) == 0 ? sgn(y - b.y) < 0 : x < b.x; } 23 inline Point operator - (const Point &b) const { return Point(x - b.x, y - b.y); } 24 inline double operator ^ (const Point &b) const { return x * b.y - y * b.x; } 25 inline double operator * (const Point &b) const { return x * b.x + y * b.y; } 26 }; 27 28 inline double seg(Point O, Point A, Point B) 29 { 30 if (sgn(B.x - A.x) == 0) return (O.y - A.y) / (B.y - A.y); 31 return (O.x - A.x) / (B.x - A.x); 32 } 33 34 struct Polygon 35 { 36 int n; 37 Point p[30]; 38 inline void scan(int _n) 39 { 40 n = _n; 41 for (int i = 0; i < n; ++i) 42 p[i].scan(); 43 } 44 inline double getarea() 45 { 46 double sum = 0; 47 for (int i = 0; i < n; ++i) 48 sum += (p[i] ^ p[(i + 1) % n]); 49 return fabs(sum) / 2; 50 } 51 }poly[N]; 52 53 int n; 54 pair <double, int> s[N]; 55 56 inline double Polyunion(int n) 57 { 58 double res = 0; 59 for (int i = 1; i <= n; ++i) 60 { 61 int sz = poly[i].n; 62 for (int j = 0; j < sz; ++j) 63 { 64 int m = 0; 65 s[m++] = mkp(0, 0); 66 s[m++] = mkp(1, 0); 67 Point a = poly[i].p[j], b = poly[i].p[(j + 1) % sz]; 68 for (int k = 1; k <= n; ++k) 69 { 70 if (i != k) 71 { 72 int sz2 = poly[k].n; 73 for (int ii = 0; ii < sz2; ++ii) 74 { 75 Point c = poly[k].p[ii], d = poly[k].p[(ii + 1) % sz2]; 76 int c1 = sgn((b - a) ^ (c - a)); 77 int c2 = sgn((b - a) ^ (d - a)); 78 if (c1 == 0 && c2 == 0) 79 { 80 if (sgn((b - a) * (d - c))) 81 { 82 s[m++] = mkp(seg(c, a, b), 1); 83 s[m++] = mkp(seg(c, a, b), -1); 84 } 85 } 86 else 87 { 88 double s1 = (d - c) ^ (a - c); 89 double s2 = (d - c) ^ (b - c); 90 if (c1 >= 0 && c2 < 0) s[m++] = mkp(s1 / (s1 - s2), 1); 91 else if (c1 < 0 && c2 >= 0) s[m++] = mkp(s1 / (s1 - s2), -1); 92 } 93 } 94 } 95 } 96 sort(s, s + m); 97 double pre = min(max(s[0].first, 0.0), 1.0), now, sum = 0; 98 int cov = s[0].second; 99 for (int j = 1; j < m; ++j) 100 { 101 now = min(max(s[j].first, 0.0), 1.0); 102 if (!cov) sum += now - pre; 103 cov += s[j].second; 104 pre = now; 105 } 106 res += (a ^ b) * sum; 107 } 108 } 109 return fabs(res) / 2; 110 } 111 112 113 inline void Run() 114 { 115 while (scanf("%d", &n) != EOF) 116 { 117 double tot = 0; 118 for (int i = 1, m; i <= n; ++i) 119 { 120 scanf("%d", &m); 121 poly[i].scan(m); 122 tot += poly[i].getarea(); 123 } 124 printf("%.10f %.10f\n", tot, Polyunion(n)); 125 } 126 } 127 128 int main() 129 { 130 #ifdef LOCAL 131 freopen("Test.in", "r", stdin); 132 #endif 133 134 Run(); 135 136 return 0; 137 }