uva 1475 - Jungle Outpost

半平面交,二分;

注意,题目的点是顺时针给出的;

  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 }
View Code

 

转载于:https://www.cnblogs.com/yours1103/p/3409300.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值