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