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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM