Most Distant Point from the Sea UVALive - 3890(半平面交)
Most Distant Point from the Sea
题意:给n个点(凸包),让求距离边界最远的点到边界的距离.
二分答案, 若所有边的半平面交不为空则有解.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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\n", Ls); 124 } 125 return 0; 126 }