Manors HDU

Manors

HDU - 5462

题意:有n个人,每个人占据m个点,每个人所属区域是该区域内的点到自己控制的点的距离小于其他人.

化简一下题目给的式子,得到直线方程,半平面交求解即可~

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const double pi = acos(-1.0);
  4 const int maxn = 110;
  5 const int inf = 0x3f3f3f3f;
  6 const double eps = 1e-8;
  7 struct Point {
  8     double x,y;
  9     Point (double x = 0, double y = 0) : x(x), y(y) {}
 10 };
 11 typedef Point Vector;
 12 Vector operator + (Vector a, Vector b) {
 13     return Vector (a.x + b.x, a.y + b.y);
 14 }
 15 Vector operator * (Vector a, double s) {
 16     return Vector (a.x * s, a.y * s);
 17 }
 18 Vector operator / (Vector a, double p) {
 19     return Vector (a.x / p, a.y / p);
 20 }
 21 Vector operator - (Point a, Point b) {
 22     return Vector (a.x - b.x, a.y - b.y);
 23 }
 24 bool operator < (Point a, Point b) {
 25     return a.x < b.x || (a.x == b.x && a.y < b.y);
 26 }
 27 int dcmp (double x) {
 28     if(fabs(x) < eps) return 0;
 29     return x < 0 ? -1 : 1;
 30 }
 31 bool operator == (const Point &a, const Point &b) {
 32     return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
 33 }
 34 double Dot(Vector a, Vector b) {
 35     return a.x * b.x + a.y * b.y;
 36 }
 37 double Angle(Vector a){
 38     return atan2(a.y, a.x);
 39 }
 40 double Length(Vector a) {
 41     return sqrt(Dot(a, a));
 42 }
 43 double Cross (Vector a, Vector b) {
 44     return a.x * b.y - a.y * b.x;
 45 }
 46 //半平面交
 47 struct Line {
 48     Point p;
 49     Vector v;
 50     double rad;
 51     Line () {}
 52     Line (Point p, Vector v) : p(p), v(v) {
 53         rad = atan2(v.y, v.x);
 54     }
 55     bool operator < (const Line &L) const {
 56         return rad < L.rad;
 57     }
 58 };
 59 bool OnLeft(Line L, Point p) {
 60     return Cross(L.v, p - L.p) > 0;
 61 }
 62 Point GetLineIntersection (Line a, Line b) {
 63     Vector u = a.p - b.p;
 64     double t = Cross(b.v, u) / Cross(a.v, b.v);
 65     return a.p + a.v*t;
 66 }
 67 
 68 int HalfplaneIntersection(Line *L, int n, Point *poly) {
 69     sort(L, L+n);
 70     int first,last;
 71     Point *p = new Point[n];
 72     Line *q = new Line[n];  //双端队列
 73     q[first = last = 0] = L[0];
 74     for(int i = 1; i < n; i++) {
 75         while(first < last && !OnLeft(L[i], p[last-1])) last--;   //去尾
 76         while(first < last && !OnLeft(L[i], p[first])) first++; 
 77         q[++last] = L[i];
 78         if(dcmp(Cross(q[last].v, q[last-1].v)) == 0) {
 79             last--;
 80             if(OnLeft(q[last], L[i].p)) q[last] = L[i];
 81         }
 82         if(first < last) p[last-1] = GetLineIntersection (q[last-1],q[last]);
 83     }
 84     while(first < last && !OnLeft(q[first], p[last-1])) last--;  //删除无用平面
 85     if(last - first <= 1) {
 86         delete []p;
 87         delete []q;
 88        return 0;  //空集    
 89     }
 90     p[last] = GetLineIntersection (q[last], q[first]);
 91     int m = 0;
 92     for(int i = first; i <= last; i++) poly[m++] = p[i];
 93     delete []p;
 94     delete []q;
 95     return m;
 96 }
 97 
 98 double ConvexPolygonArea(Point *p, int n) {
 99     double area = 0;
100     for(int i = 1; i < n-1; i++) {
101         area += Cross(p[i] - p[0], p[i+1] - p[0]);
102     }
103     return area / 2;
104 }
105 double X[maxn], Y[maxn], FX[maxn], FY[maxn];
106 Point poly[maxn], p1[6];
107 Line line[maxn];
108 int main(){
109     //freopen("in.txt", "r", stdin);
110     int t, kase = 0;
111     scanf("%d", &t);
112     while(t--){
113         int n, m;
114         scanf("%d %d", &n, &m);
115         double x, y;
116         for(int i = 0; i < n; i++){
117             X[i] = Y[i] = FX[i] = FY[i] = 0;
118             for(int j = 0; j < m; j++){
119                 scanf("%lf %lf", &x, &y);
120                 X[i] += x;
121                 Y[i] += y;
122                 FX[i] += x*x;
123                 FY[i] += y*y;
124             }
125         }
126         int cnt = 0;
127         p1[0] = Point(0, 4095); p1[1] = Point(0, 0);
128         p1[2] = Point(4095, 0); p1[3] = Point(4095, 4095);
129         printf("Case #%d:", ++kase);
130         for(int i = 0 ; i < n; i++){
131             cnt = 0;
132             for(int j = 0; j < n; j++) if(i!=j){
133                 double a = 2 * (X[i] - X[j]);
134                 double b = 2 * (Y[i] - Y[j]);
135                 double c = FX[j] + FY[j] - FX[i] - FY[i];
136                 Vector v = Vector(b, -a);
137                 Point p;
138                 if(fabs(a) > fabs(b)) p = Point(-c/a, 0);
139                 else p = Point(0, -c/b);
140                 line[cnt++] = Line(p, v);
141             }
142             for(int i = 0; i < 4; i++){
143                 line[cnt++] = Line(p1[i], p1[(i+1)%4] - p1[i]);
144             }
145             int sz = HalfplaneIntersection(line, cnt, poly);
146             double ans = ConvexPolygonArea(poly, sz);
147             printf(" %d", int(ans+0.5));
148         }
149         puts("");
150     }
151     return 0;
152 }
View Code
原文地址:https://www.cnblogs.com/yijiull/p/7688878.html