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;
}

 

posted @ 2012-05-23 13:50  'wind  阅读(4197)  评论(0编辑  收藏  举报