HLG 1429 凸多边形【快速判断点在凸多边形内】
题意: 有一个 n 个点组成的凸多边形, 和 m 个点,问 M 个点是否全部严格在多边形内部。
转大牛分析:
考虑将一个凸包划分为N个三角区域
于是可知对于某个点,如果不在这些三角区域内,那么必然不在凸包内
否则,可以通过二分位置,得到点所在的区间
之后只需要判断点 是否在区间所对应的原凸包的边的左边即可(逆时针给出凸包点顺序)
假设我们查询绿色的点是否在凸包内,我们首先二分得到了它所在的区间,然后判断它和绿色的向量的关系,蓝色和紫色的点类似,蓝色的点在边界上,紫色的点在边界右边
因此一个查询在O(logN)内解决
code:
View Code
#include<stdio.h> #include<string.h> struct node { long long x,y; }a[100005],b[100005]; long long mul(node p1,node p2,node p3) { return (p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y); } int main() { int n,m,i,low,high,mid,flag; while(scanf("%d",&n)!=EOF) { for(i=0;i<n;i++) scanf("%lld%lld",&a[i].x,&a[i].y); scanf("%d",&m); for(i=0;i<m;i++) scanf("%lld%lld",&b[i].x,&b[i].y); flag=0; for(i=0;i<m;i++) { if(mul(a[0],a[1],b[i])>=0||mul(a[0],a[n-1],b[i])<=0) { flag=1; goto loop; } low=2; high=n-1; while(low<high) { mid=(low+high)>>1; if(mul(a[0],a[mid],b[i])>0) high=mid; else low=mid+1; } if(mul(a[low],a[low-1],b[i])<=0) { flag=1; goto loop; } } loop: if(flag) printf("NO\n"); else printf("YES\n"); } return 0; }