uva 1396 - Most Distant Point from the Sea
半平面的交,二分的方法;
1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 #define eps 1e-6 5 using namespace std; 6 7 int dcmp(double x) 8 { 9 return fabs(x) < eps ? 0 : (x > 0 ? 1 : -1); 10 } 11 12 struct Point 13 { 14 double x; 15 double y; 16 Point(double x = 0, double y = 0):x(x), y(y) {} 17 }; 18 typedef Point Vector; 19 20 Vector operator + (Point A, Point B) 21 { 22 return Vector(A.x + B.x, A.y + B.y); 23 } 24 25 Vector operator - (Point A, Point B) 26 { 27 return Vector(A.x - B.x, A.y - B.y); 28 } 29 30 Vector operator * (Point A, double p) 31 { 32 return Vector(A.x * p, A.y * p); 33 } 34 35 Vector operator / (Point A, double p) 36 { 37 return Vector(A.x / p, A.y / p); 38 } 39 double dot(Point a,Point b) 40 { 41 return a.x*b.x+a.y*b.y; 42 } 43 double cross(Point a,Point b) 44 { 45 return a.x*b.y-a.y*b.x; 46 } 47 48 Vector nomal(Vector a) 49 { 50 double l=sqrt(dot(a,a)); 51 return Vector(-a.y/l,a.x/l); 52 } 53 54 struct line 55 { 56 Point p; 57 Vector v; 58 double ang; 59 line() {} 60 line(Point p,Vector v):p(p),v(v) 61 { 62 ang=atan2(v.y,v.x); 63 } 64 bool operator<(const line &t)const 65 { 66 return ang<t.ang; 67 } 68 }; 69 70 bool onleft(line l,Point p) 71 { 72 return (cross(l.v,p-l.p)>0); 73 } 74 75 Point getintersection(line a,line b) 76 { 77 Vector u=a.p-b.p; 78 double t=cross(b.v,u)/cross(a.v,b.v); 79 return a.p+a.v*t; 80 } 81 82 int halfplanintersection(line *l,int n,Point *poly) 83 { 84 sort(l,l+n); 85 int first,last; 86 Point *p=new Point[n]; 87 line *q=new line[n]; 88 q[first=last=0]=l[0]; 89 for(int i=1; i<n; i++) 90 { 91 while(first<last && !onleft(l[i],p[last-1]))last--; 92 while(first<last && !onleft(l[i],p[first]))first++; 93 q[++last]=l[i]; 94 if(fabs(cross(q[last].v,q[last-1].v))<eps) 95 { 96 last--; 97 if(onleft(q[last],l[i].p))q[last]=l[i]; 98 } 99 if(first<last)p[last-1]=getintersection(q[last-1],q[last]); 100 } 101 while(first<last && !onleft(q[first],p[last-1]))last--; 102 if((last-first )<=1)return 0; 103 p[last]=getintersection(q[last],q[first]); 104 int m=0; 105 for(int i=first; i<=last; i++)poly[m++]=p[i]; 106 return m; 107 } 108 109 Point p[200],poly[200]; 110 line l[200]; 111 Point v[200],v2[200]; 112 int main() 113 { 114 int n,m; 115 double x,y; 116 while(scanf("%d",&n)&&n) 117 { 118 for(int i=0; i<n; i++) 119 { 120 scanf("%lf%lf",&x,&y); 121 p[i]=Point(x,y); 122 } 123 for(int i=0; i<n; i++) 124 { 125 v[i]=p[(i+1)%n]-p[i]; 126 v2[i]=nomal(v[i]); 127 } 128 double left=0.0,right=20000.0; 129 while(right-left>eps) 130 { 131 double mid=(left+right)/2; 132 for(int i=0; i<n; i++) 133 l[i]=line(p[i]+v2[i]*mid,v[i]); 134 m=halfplanintersection(l,n,poly); 135 if(!m)right=mid; 136 else left=mid; 137 } 138 printf("%.6lf\n",left); 139 } 140 return 0; 141 }