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 }
View Code

相关文章: