Most Distant Point from the Sea UVALive

Most Distant Point from the Sea

 UVALive - 3890 

题意:给n个点(凸包),让求距离边界最远的点到边界的距离.

二分答案, 若所有边的半平面交不为空则有解.

  1 /*************************************************************************
  2     > File Name: board.cpp
  3     > Author: yijiull
  4     > Mail: 1147161372@qq.com 
  5     > Created Time: 2017年09月22日 星期五 21时19分51秒
  6  ************************************************************************/
  7 #include <iostream>
  8 #include <cstring>
  9 #include <cstdio>
 10 #include <bits/stdc++.h>
 11 using namespace std;
 12 #define FP freopen("in.txt", "r", stdin)
 13 const double eps = 1e-12;
 14 const int inf = 0x3f3f3f3f;
 15 struct Point {
 16     double x,y;
 17     Point (double x = 0, double y = 0) : x(x), y(y) {}
 18 };
 19 typedef Point Vector;
 20 Vector operator + (Vector a, Vector b) {
 21     return Vector (a.x + b.x, a.y + b.y);
 22 }
 23 Vector operator * (Vector a, double s) {
 24     return Vector (a.x * s, a.y * s);
 25 }
 26 Vector operator / (Vector a, double p) {
 27     return Vector (a.x / p, a.y / p);
 28 }
 29 Vector operator - (Point a, Point b) {
 30     return Vector (a.x - b.x, a.y - b.y);
 31 }
 32 bool operator < (Point a, Point b) {
 33     return a.x < b.x || (a.x == b.x && a.y < b.y);
 34 }
 35 int dcmp (double x) {
 36     if(fabs(x) < eps) return 0;
 37     return x < 0 ? -1 : 1;
 38 }
 39 bool operator == (const Point &a, const Point &b) {
 40     return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
 41 }
 42 double Dot(Vector a, Vector b) {
 43     return a.x * b.x + a.y * b.y;
 44 }
 45 double Length (Vector a) {
 46     return sqrt(Dot(a, a));
 47 }
 48 double Cross (Vector a, Vector b) {
 49     return a.x * b.y - a.y * b.x;
 50 }
 51 Vector Normal (Vector a) {
 52     double L = Length(a);
 53     return Vector(-a.y / L, a.x / L);
 54 }
 55 //半平面交
 56 struct Line{
 57     Point p;
 58     Vector v;
 59     double rad;
 60     Line () {}
 61     Line (Point p, Vector v) : p(p), v(v) {
 62         rad = atan2(v.y,v.x);
 63     }
 64     bool operator < (const Line &L) const {
 65         return rad < L.rad;
 66     }
 67 };
 68 bool OnLeft(Line L, Point p) {
 69     return Cross(L.v, p - L.p) > 0;
 70 }
 71 Point GetLineIntersection (Line a, Line b) {
 72     Vector u = a.p - b.p;
 73     double t = Cross(b.v, u) / Cross(a.v, b.v);
 74     return a.p + a.v*t;
 75 }
 76 int HalfplaneIntersection(Line *L, int n, Point *poly) {
 77     sort(L, L+n);
 78     int first,last;
 79     Point *p = new Point[n];
 80     Line *q = new Line[n];  //双端队列
 81     q[first = last = 0] = L[0];
 82     for(int i = 1; i < n; i++) {
 83         while(first < last && !OnLeft(L[i], p[last-1])) last--;   //去尾
 84         while(first < last && !OnLeft(L[i], p[first])) first++; 
 85         q[++last] = L[i];
 86         if(dcmp(Cross(q[last].v, q[last-1].v)) == 0) {
 87             last--;
 88             if(OnLeft(q[last], L[i].p)) q[last] = L[i];
 89         }
 90         if(first < last) p[last-1] = GetLineIntersection (q[last-1],q[last]);
 91     }
 92     while(first < last && !OnLeft(q[first], p[last-1])) last--;  //删除无用平面
 93     if(last - first <= 1) return 0;  //空集
 94     p[last] = GetLineIntersection (q[last], q[first]);
 95     int m = 0;
 96     for(int i = first; i <= last; i++) poly[m++] = p[i];
 97     return m;
 98 }
 99 Point p[200], poly[200];
100 Line L[200];
101 Vector v[200], v2[200];
102 int main(){
103     int n;
104     //FP;
105     while(scanf("%d", &n) && n) {
106         int m, x, y;
107         for(int i = 0; i < n; i++) {
108             scanf("%d%d", &x, &y);
109             p[i] = Point(x,y);
110         }
111         for(int i = 0; i < n; i++) {
112             v[i] = p[(i+1)%n] - p[i];
113             v2[i] = Normal(v[i]);
114         }
115         double Ls = 0, Rs = 20000;
116         while(Rs - Ls > 1e-6) {
117             double mid = Ls + (Rs - Ls)/2;
118             for(int i = 0; i < n; i++) L[i] = Line(p[i] + v2[i]*mid, v[i]);
119             m = HalfplaneIntersection (L, n, poly);
120             if(!m) Rs = mid;
121             else Ls = mid;
122         }
123         printf("%.6lf
", Ls);
124     }
125     return 0;
126 }
View Code
原文地址:https://www.cnblogs.com/yijiull/p/7577589.html