【BZOJ4445】【SCOI2015】小凸想跑步 半平面交

用半平面交计算可行区域面积,除以总面积,得到概率。

假设当前站位的坐标为p(x,y),根据三角形面积最小,建立不等式关系。

  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <cstdio>
  4 #include <cmath>
  5 #include <algorithm>
  6 
  7 using namespace std;
  8 
  9 const int N = 400000 + 5;
 10 const double eps = 1e-8;
 11 
 12 inline int sgn(double x) {
 13     return (x > eps) - (x < -eps);
 14 }
 15 struct Point {
 16     double x, y;
 17     Point(double x = 0, double y = 0): x(x), y(y) {}
 18     void read() {
 19         scanf("%lf%lf", &x, &y);
 20     }
 21     void write() {
 22         printf("%.2lf %.2lf\n", x, y);
 23     }
 24     Point operator + (const Point &t)const {
 25         return Point(x + t.x, y + t.y);
 26     }
 27     Point operator - (const Point &t)const {
 28         return Point(x - t.x, y - t.y);
 29     }
 30     double operator * (const Point &t)const {
 31         return x * t.x + y * t.y;
 32     }
 33     double operator ^ (const Point &t)const {
 34         return x * t.y - y * t.x;
 35     }
 36 } P[N], poly[N];
 37 #define Cross(a,b) ((a)^(b))
 38 struct Line {
 39     Point s, v;
 40     double ang;
 41     Line() {}
 42     Line(Point s, Point v): s(s), v(v) {
 43         ang = atan2(v.y, v.x);
 44     }
 45     bool operator < (const Line &t)const {
 46         if (sgn(ang - t.ang) != 0) return ang < t.ang;
 47         return Cross(s - t.s, t.v) < 0;
 48     }
 49     Point operator & (const Line &t)const {
 50         double a = Cross(t.s - s, t.v);
 51         double b = Cross(v, t.v);
 52         Point ret = s;
 53         ret.x += v.x * a / b;
 54         ret.y += v.y * a / b;
 55         return ret;
 56     }
 57 } L[N], Q[N];
 58 
 59 double Area(Point *P, int n) {
 60     double area = 0;
 61     for (int i = 1; i <= n; i ++)
 62         area += Cross(P[i], P[i % n + 1]);
 63     return area * 0.5;
 64 }
 65 void HPI(Line *L, int n, int &cnt) {
 66     sort(L + 1, L + 1 + n);
 67     int l = 1, r = 2, m = 1;
 68     for (int i = 2; i <= n; i ++)
 69         if (fabs(L[i].ang - L[i - 1].ang) > eps)
 70             L[++m] = L[i];
 71     Q[1] = L[1], Q[2] = L[2];
 72     for (int i = 3; i <= m; i ++) {
 73         if (sgn(Q[r].v ^ Q[r - 1].v) == 0) return;
 74         if (sgn(Q[l].v ^ Q[l + 1].v) == 0) return;
 75         while (l < r && Cross((Q[r]&Q[r - 1]) - L[i].s, L[i].v) > eps) --r;
 76         while (l < r && Cross((Q[l]&Q[l + 1]) - L[i].s, L[i].v) > eps) ++l;
 77         Q[++r] = L[i];
 78     }
 79     while (l < r && Cross((Q[r]&Q[r - 1]) - Q[l].s, Q[l].v) > eps) --r;
 80     while (l < r && Cross((Q[l]&Q[l + 1]) - Q[r].s, Q[r].v) > eps) ++l;
 81     if (r - l <= 1) return;
 82     Q[r + 1] = Q[l];
 83     cnt = 0;
 84     for (int i = l; i <= r; i ++)
 85         poly[++cnt] = Q[i] & Q[i + 1];
 86 }
 87 
 88 /*
 89     a*x + b*y + c < 0
 90     (x-x1)*(y2-y1)-(y-y1)*(x2-x1) < (x-x3)*(y4-y3)-(y-y3)*(x4-x3)
 91     (y2-y1)*x-(y4-y3)*x - (x2-x1)*y+(x4-x3)*y - (y2-y1)*x1+(x2-x1)*y1+(y4-y3)*x3-(x4-x3)*y3 < 0
 92 */
 93 void init(int n, int &cnt) {
 94     cnt = 0;
 95     Point s, v;
 96     double x1 = P[1].x, x2 = P[2].x;
 97     double y1 = P[1].y, y2 = P[2].y;
 98     for (int i = 2; i <= n; i ++) {
 99         double x3 = P[i].x, x4 = P[i + 1].x;
100         double y3 = P[i].y, y4 = P[i + 1].y;
101         double a = (y2 - y1) - (y4 - y3);
102         double b = (x4 - x3) - (x2 - x1);
103         double c = -x1 * y2 + x2 * y1 + x3 * y4 - x4 * y3;
104         v = Point(b, -a);
105         if (sgn(a)) s = Point(-c / a, 0);
106         else s = Point(0, -c / b);
107         L[++cnt] = Line(s, v);
108     }
109     for (int i = 1; i <= n; i ++)
110         L[++cnt] = Line(P[i], P[i + 1] - P[i]);
111 }
112 
113 int n, m, k;
114 void data() {
115     scanf("%d", &n);
116     for (int i = 1; i <= n; i ++)    P[i].read();
117     P[n + 1] = P[1];
118 }
119 int main() {
120     data();
121     init(n, k);
122     HPI(L, k, m);
123     double a = Area(poly, m);
124     double b = Area(P, n);
125     printf("%.4lf\n", fabs(a / b));
126     return 0;
127 }
View Code

 

posted @ 2016-03-30 19:44  羁旅  阅读(182)  评论(0编辑  收藏  举报