【GDCPC H】【HDU5243】Homework

给出平面上的N个点 
对于平面上的一点p,要求任何一条通过p且不经过上面N个点的直线,其两侧的点数都不少于N/3 
问符合上面要求的点形成的区域的面积是多少

假如一个点一侧有少于n/3个点,这个点这一侧所有点都不可能

因此对于所有右侧恰好有n/3 - 1个点的直线做半平面交就是答案

  1 #include <cstdio>
  2 #include <iostream>
  3 #include <cmath>
  4 #include <algorithm>
  5 using namespace std;
  6 #define V P
  7 const double eps = 1e-6;
  8 inline int dcmp (double x) {
  9     return x < -eps ? -1 : x > eps;
 10 }
 11 struct P {
 12     double x, y;
 13     void scan() {
 14         scanf("%lf%lf", &x, &y);
 15     }
 16     P(double _x = 0, double _y = 0) : x(_x), y(_y) { }
 17     V operator + (V a) const {
 18         return V(x + a.x, y + a.y);
 19     }
 20     V operator - (V a) const {
 21         return V(x - a.x, y - a.y);
 22     }
 23     V operator * (double p) const {
 24         return V(p * x, p * y);
 25     }
 26     V operator / (double p) const {
 27         return V(x / p, y / p);
 28     }
 29     bool operator < (P a) const {
 30         return x < a.x || (dcmp(x - a.x) == 0 && y < a.y);
 31     }
 32     bool operator == (P a) const {
 33         return dcmp(x - a.x) == 0 && dcmp(y - a.y) == 0;
 34     }
 35 };
 36 
 37 inline double dot(V a, V b) {
 38     return a.x * b.x + a.y * b.y;
 39 }
 40 inline double len(V a) {
 41     return sqrt(dot(a, a));
 42 }
 43 inline double dis(P a, P b) {
 44     return len(b - a);
 45 }
 46 inline double ang(V a, V b) {
 47     return acos(dot(a, b) / len(a) / len(b));
 48 }
 49 inline double cross(V a, V b) {
 50     return a.x * b.y - a.y * b.x;
 51 }
 52 inline double area(P a, P b, P c) {
 53     return cross(b - a, c - a);
 54 }
 55 V rot(V a, double p) {
 56     return V(a.x * cos(p) - a.y * sin(p), a.x * sin(p) + a.y * cos(p));
 57 }
 58 V normal(V a) {
 59     double L = len(a);
 60     return V(-a.y / L, a.x / L);
 61 }
 62 P inter(P p, V v, P q, V w) {
 63     V u = p - q;
 64     double t = cross(w, u) / cross(v, w);
 65     return p + v * t;
 66 }
 67 double dis(P p, P a, P b) {
 68     V v1 = b - a, v2 = p - a;
 69     return fabs(cross(v1, v2)) / len(v1);
 70 }
 71 double dis2(P p, P a, P b) {
 72     if (a == b) return len(p - a);
 73     V v1 = b - a, v2 = p - a, v3 = p - b;
 74     if (dcmp(dot(v1, v2)) < 0) return len(v2);
 75     else if (dcmp(dot(v1, v3)) > 0) return len(v3);
 76     else return fabs(cross(v1, v2)) / len(v1);
 77 }
 78 P proj(P p, P a, P b) {
 79     V v = b - a;
 80     return a + v * (dot(v, p - a) / dot(v, v));
 81 }
 82 bool isInter(P a1, P a2, P b1, P b2) {
 83     double c1 = cross(a2 - a1, b1 - a1), c2 = cross(a2 - a1, b2 - a1),
 84            c3 = cross(b2 - b1, a1 - b1), c4 = cross(b2 - b1, a2 - b1);
 85     return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
 86 }
 87 bool onSeg(P p, P a1, P a2) {
 88     return dcmp(cross(a1 - p, a2 - p)) == 0 && dcmp(dot(a1 - p, a2 - p)) < 0;
 89 }
 90 
 91 double area(P* p, int n) {
 92     double s = 0;
 93     p[n] = p[0];
 94     for (int i = 1; i < n; i ++)
 95         s += cross(p[i] - p[0], p[i + 1] - p[0]);
 96     return s / 2;
 97 }
 98 int graham(P* p, int n, P* ch) {
 99     sort(p, p + n);
100     int m = 0;
101     for (int i = 0; i < n; i ++) {
102         while (m > 1 && cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2]) <= 0) m --;
103         ch[m ++] = p[i];
104     }
105     int k = m;
106     for (int i = n - 2; i >= 0; i --) {
107         while (m > k && cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2]) <= 0) m --;
108         ch[m ++] = p[i];
109     }
110     if (n > 1) m --;
111     return m;
112 }
113 struct L {
114     P p;
115     V v;
116     double ang;
117     L() {}
118     L(P _p, V _v) : p(_p), v(_v) { ang = atan2(v.y, v.y); }
119     bool operator < (const L& L) const {
120         return ang < L.ang;
121     }
122 };
123 inline int get(P a) {
124     if( a.x > 0 && a.y >= 0) return 1;
125     if( a.x <= 0 && a.y > 0) return 2;
126     if( a.x < 0 && a.y <= 0) return 3;
127     if( a.x >= 0 && a.y < 0) return 4;
128     return 0;
129 }
130 inline bool cmp2 (L a, L b) {
131     return get(a.v) < get(b.v) || (get(a.v) == get(b.v) && dcmp( cross(a.v, b.v) ) >0);
132 }
133 bool onLeft(L l, P p) {
134     return cross(l.v, p - l.p) > 0;
135 }
136 P inter(L a, L b) {
137     return inter(a.p, a.v, b.p, b.v);
138 }
139 int half(L* l, int n, P* po) {
140     sort(l, l + n, cmp2);
141     int h, t;
142     P *p = new P[n];
143     L *q = new L[n];
144     q[h = t = 0] = l[0];
145     for (int i = 1; i < n; i ++) {
146         while (h < t && !onLeft(l[i], p[t - 1])) t --;
147         while (h < t && !onLeft(l[i], p[h])) h ++;
148         q[++ t] = l[i];
149         if (dcmp(cross(q[t].v, q[t - 1].v)) == 0) {
150             t --;
151             if (onLeft(q[t], l[i].p)) q[t] = l[i];
152         }
153         if (h < t) p[t - 1] = inter(q[t - 1], q[t]);
154     }
155     while (h < t && !onLeft(q[h], p[t - 1])) t --;
156     if (t - h <= 1) return 0;
157     p[t] = inter(q[t], q[h]);
158     int m = 0;
159     for (int i = h; i <= t; i ++) po[m ++] = p[i];
160     return m;
161 }
162 inline bool cmp (V a, V b) {
163     return get(a) < get(b) || (get(a) == get(b) && dcmp( cross(a, b) ) >0);
164 }
165 const int N = 101000;
166 int n;
167 P a[N], b[N], res[N];
168 L l[N];
169 int main() {
170     freopen("a.in", "r", stdin);
171     int T;
172     scanf("%d", &T);
173     for (int cas = 1; cas <= T; cas ++) {
174         scanf("%d", &n);
175         for (int i = 0; i < n; i ++)
176             a[i].scan();
177         int bound = n / 3 - 1, l_c = 0;
178         for (int i = 0; i < n; i ++) {
179             int cnt = 0;
180             for (int j = 0; j < n; j ++)
181                 if (j != i)
182                     b[cnt ++] = a[j] - a[i];
183             sort(b, b + cnt, cmp);
184             int t = 0, sum = 0;
185             for (int j = 0; j < cnt; j ++) {
186                 //if (j == 1) printf("fuck %d %d\n", dcmp(cross(b[j], b[(t + 1) % cnt])), dcmp(dot(b[j], b[(t + 1) % cnt])));
187                 while ((dcmp(cross(b[j], b[(t + 1) % cnt])) == 1) ||
188                         (dcmp(cross(b[j], b[(t + 1) % cnt])) == 0 &&
189                          dcmp(dot(b[j], b[(t + 1) % cnt])) == -1)) t = (t + 1) % cnt, sum ++;
190                 if (cnt - (sum + 1) == bound) l[l_c ++] = L(a[i], b[j]);
191                 //if (i == 0) printf("%d\n", sum);
192                 if (t == j) t ++;
193                 else {
194                     while (dcmp(cross(b[j], b[(j + 1) % cnt])) == 0) j ++, sum --;
195                     sum --;
196                 }
197             }
198         }
199         //printf("%d\n", l_c);
200         //for (int i = 0; i < l_c; i ++)
201         //    printf("%lf %lf %lf %lf\n", l[i].p.x, l[i].p.y, l[i].v.x, l[i].v.y);
202         int ans = half(l, l_c, res);
203         //printf("%d\n", ans);
204         //for (int i = 0; i < ans; i ++)
205         //    printf("%lf %lf\n", res[i].x, res[i].y);
206         printf("Case #%d: %.6lf\n", cas, area(res, ans));
207     }
208     return 0;
209 }

 

posted @ 2015-06-14 00:31  Moretimes  阅读(536)  评论(0编辑  收藏  举报