POJ 3525 半平面交+二分

二分所能形成圆的最大距离,然后将每一条边都向内推进这个距离,最后所有边组合在一起判断时候存在内部点

  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
" , bin_search(p , n));
124     }
125 }
原文地址:https://www.cnblogs.com/CSU3901130321/p/4668897.html