二分所能形成圆的最大距离,然后将每一条边都向内推进这个距离,最后所有边组合在一起判断时候存在内部点
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <cmath> 6 7 using namespace std; 8 #define N 105 9 #define ll long long 10 #define eps 1e-7 11 12 int dcmp(double x) 13 { 14 if(fabs(x)<eps) return 0; 15 else return x<0?-1:1; 16 } 17 18 struct Point{ 19 double x,y; 20 Point(double x=0 , double y=0):x(x),y(y){} 21 }p[N] , poly[N]; 22 23 typedef Point Vector; 24 25 struct Line{ 26 Point p; 27 Vector v; 28 double ang; 29 Line(){} 30 Line(Point p , Vector v):p(p),v(v){ang = atan2(v.y , v.x);} 31 bool operator<(const Line &m) const{ 32 return dcmp(ang-m.ang)<0; 33 } 34 }line[N]; 35 36 Vector operator+(Vector a , Vector b){return Vector(a.x+b.x , a.y+b.y);} 37 Vector operator-(Vector a , Vector b){return Vector(a.x-b.x , a.y-b.y);} 38 Vector operator*(Vector a , double b){return Vector(a.x*b , a.y*b);} 39 Vector operator/(Vector a , double b){return Vector(a.x/b , a.y/b);} 40 41 double Cross(Vector a , Vector b){return a.x*b.y-a.y*b.x;} 42 double Dot(Vector a , Vector b){return a.x*b.x+a.y*b.y;} 43 double Len(Vector a){return sqrt(Dot(a,a));} 44 45 bool OnLeft(Line L , Point P) 46 { 47 return dcmp(Cross(L.v , P-L.p))>0; 48 } 49 50 Point GetIntersection(Line a , Line b) 51 { 52 Vector u = a.p-b.p; 53 double t = Cross(b.v , u)/Cross(a.v , b.v); 54 return a.p+a.v*t; 55 } 56 57 Vector Normal(Vector a) 58 { 59 double l = Len(a); 60 return Vector(-a.y , a.x)/l; 61 } 62 63 int HalfplaneIntersection(Line *L , int n , Point *poly) 64 { 65 sort(L , L+n); 66 int first , last; 67 Point *p = new Point[n]; 68 Line *q = new Line[n]; 69 q[first=last=0] = L[0]; 70 for(int i=1 ; i<n ; i++){ 71 while(first<last && !OnLeft(L[i] , p[last-1])) last--; 72 while(first<last && !OnLeft(L[i] , p[first])) first++; 73 q[++last] = L[i]; 74 if(fabs(Cross(q[last].v , q[last-1].v))<eps){ 75 last--; 76 if(OnLeft(q[last] , L[i].p)) q[last]=L[i]; 77 } 78 if(first < last) p[last-1] = GetIntersection(q[last-1] , q[last]); 79 } 80 while(first<last && !OnLeft(q[first] , p[last-1])) last--; 81 if(last-first<=1) return 0; 82 p[last] = GetIntersection(q[last] , q[first]); 83 int m=0; 84 for(int i=first ; i<=last ; i++) poly[m++] = p[i]; 85 return m; 86 } 87 88 double calArea(Point *p , int n) 89 { 90 if(!n) return 0; 91 double ret = 0; 92 for(int i=2 ; i<n ; i++){ 93 ret += Cross(p[i-1]-p[0],p[i]-p[0]); 94 } 95 return ret/2; 96 } 97 98 double bin_search(Point *p , int n) 99 { 100 double l = 0 , r = 1e8 , m; 101 Vector unit; 102 while(r-l>=eps) 103 { 104 m = (l+r)/2; 105 for(int i=1 ; i<=n ; i++){ 106 unit = Normal(p[i]-p[i-1]); 107 line[i-1] = Line(p[i-1]+unit*m , p[i]-p[i-1]); 108 } 109 if(HalfplaneIntersection(line , n , poly)) l=m; 110 else r=m; 111 } 112 return l; 113 } 114 115 int main() 116 { 117 // freopen("in.txt" , "r" , stdin); 118 int n ; 119 while(scanf("%d" , &n) , n) 120 { 121 for(int i=0 ; i<n ; i++) scanf("%lf%lf" , &p[i].x , &p[i].y); 122 p[n] = p[0]; 123 printf("%.6f\n" , bin_search(p , n)); 124 } 125 }
时间: 2024-10-13 12:05:55