Reprinted please indicate the source, thank you http://blog.csdn.net/acm_cxlove/article/details/7854526
By --- cxlove
Question: a convex polygon is given. The vertex is a defense tower. The protection range is inside a convex polygon, excluding the boundary. Select a point inside the polygon, the maximum number of anti-DDoS towers to be destroyed by the other party.
Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 3761
First of all, thank you for your guidance.
The first thing you need to understand is the question of how to minimize the remaining protection scope for destroying a certain number of anti-DDoS towers.
The conclusion is that multiple consecutive vertices are destroyed, which is optimal and can be proved.
For a polygon with five vertices, you can delete two vertices and try to separate them with one vertex.
Because the original polygon is convex and edges, it is easier to obtain the optimal continuous vertex. In the same way, other conditions can be obtained.
The topic requires that the other party destroy at least the tower guard that needs to be destroyed as much as possible, and contact complexity.
Second answer, and then determine whether there is a region to ensure it can be protected.
For each Binary Vertex, the enumeration deletes consecutive vertices to form a new boundary. The semi-plane intersection is used to determine whether a feasible region exists.
Note: points on the boundary are unprotected, so you only need to determine the area of the polygon core.
When the remaining points are 2 and below, it is certainly feasible. Avoid handling problems.
Let's take a look at the scope of the question. There are 5 W vertices, and the half-plane intersection must at least use the nlgn algorithm. In fact, I have heard the explanation from my brother on a sunny day.
The nlgnlgn algorithm of the binary + semi-plane intersection is getting stuck, and the urine is scared immediately. Is there an O (n) Semi-plane intersection algorithm ???
Thanks to the guidance of Sunny brother, in fact, the semi-plane intersection algorithm of lift sorts all vectors by the Polar Angle and maintains a dual-end queue, and the sorting part reaches the complexity of nlgn, in fact, only O (n) is required ). Then let's look at this question again. The convex and multiple shapes were originally given in order, and the polar angles of our connections were also cyclical and ordered. We scanned them linearly to find the smallest polar angle, then we can get the ordered vector in sequence, the linear sort of O (n), and the sunny brother is so amazing.
The specific details depend on everyone's habits. I adjusted the original order to backward order. The semi-plane intersection algorithm targets the left side of the vector, while the polar angle is clockwise.
#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#define eps 1e-10#define N 50005#define zero(a) (fabs(a)<eps)using namespace std;struct Point { double x,y; Point(){} Point(double tx,double ty){x=tx;y=ty;}}p[N],q[N];int n,m;struct Segment{ Point s,e; double angle; void get_angle(){angle=atan2(e.y-s.y,e.x-s.x);}}seg[N];double xmul(Point p0,Point p1,Point p2){ return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}double Get_Area(Point pt[],int n){ double area=0; for(int i=1;i<n-1;i++) area+=xmul(pt[0],pt[i],pt[i+1]); return fabs(area)/2;}Point Get_Intersect(Segment s1,Segment s2){ double u=xmul(s1.s,s1.e,s2.s),v=xmul(s1.e,s1.s,s2.e); Point t; t.x=(s2.s.x*v+s2.e.x*u)/(u+v);t.y=(s2.s.y*v+s2.e.y*u)/(u+v); return t;}void HalfPlaneIntersect(Segment seg[],int n){ int idx; for(int i=0;i<n;i++) if(seg[i].angle+eps<seg[(i+1)%n].angle&&seg[i].angle+eps<seg[(i-1+n)%n].angle){ idx=i; break; } Segment deq[N]; deq[0]=seg[idx];deq[1]=seg[(idx+1)%n]; int head=0,tail=1; idx=(idx+2)%n; for(int i=2;i<n;i++,idx=(idx+1)%n){ while(head<tail&&xmul(seg[idx].s,seg[idx].e,Get_Intersect(deq[tail],deq[tail-1]))<-eps) tail--; while(head<tail&&xmul(seg[idx].s,seg[idx].e,Get_Intersect(deq[head],deq[head+1]))<-eps) head++; deq[++tail]=seg[idx]; } while(head<tail&&xmul(deq[head].s,deq[head].e,Get_Intersect(deq[tail],deq[tail-1]))<-eps) tail--; while(head<tail&&xmul(deq[tail].s,deq[tail].e,Get_Intersect(deq[head],deq[head+1]))<-eps) head++; m=0; if(tail==head) return; for(int i=head;i<tail;i++){ q[m++]=Get_Intersect(deq[i],deq[i+1]); } if(tail>head+1) q[m++]=Get_Intersect(deq[head],deq[tail]);}int slove(int mid){ if(n-mid<=2) return 1; for(int i=0;i<n;i++){ seg[i].s=p[i]; seg[i].e=p[(i+mid+1)%n]; seg[i].get_angle(); } HalfPlaneIntersect(seg,n); return zero(Get_Area(q,m));}int main(){ int t; scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); for(int i=1;i<=n/2;i++) swap(p[i],p[n-i]); int ans,low=0,high=n,mid; while(low<=high){ mid=(low+high)/2; if(slove(mid)){ans=mid;high=mid-1;} else low=mid+1; } printf("%d\n",ans); } return 0;}