zoukankan      html  css  js  c++  java
  • UVA 13024: Saint John Festival(凸包+二分 ,判定多个点在凸包内)

    题意:给定N个点,Q次询问,问当前点知否在N个点组成的凸包内。

    思路:由于是凸包,我们可以利用二分求解。

    二分思路1:求得上凸包和下凸包,那么两次二分,如果点在对应上凸包的下面,对应下凸包的上面,那么在凸包内。

    二分思路2:求得凸包(N),划分为N-2个三角形,二分求得对应位置,验证是否在三角形内。

    (如果不是凸包,则不能这样做。

    三角形代码:

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=100010;
    struct point{
        ll x,y;
        point(){}
        point(ll xx,ll yy):x(xx),y(yy){}
    };
    ll dot(point w,point v){ return w.x*v.x+w.y*v.y;}
    ll det(point w,point v){ return w.x*v.y-w.y*v.x;}
    point operator -(point w,point v){ return point(w.x-v.x,w.y-v.y);}
    point a[maxn],ch[maxn]; int ttop,top,N,Q,ans;
    bool cmp(point w,point v){
        if(w.x!=v.x) return w.x<v.x; return w.y<v.y;
    }void convex()
    {
        top=0;
        sort(a+1,a+N+1,cmp);
        rep(i,1,N) {
            while(top>1&&det(ch[top]-ch[top-1],a[i]-ch[top-1])<=0) top--;
            ch[++top]=a[i];
        }
        ttop=top;
        for(int i=N-1;i>=1;i--){
            while(top>ttop&&det(ch[top]-ch[top-1],a[i]-ch[top-1])<=0) top--;
            ch[++top]=a[i];
        }
    }
    bool check(point A)
    {
        int L=2,R=top-2,Mid;
        while(L<=R){
            Mid=(L+R)>>1;
            if(det(ch[Mid]-ch[1],A-ch[1])<0) R=Mid-1;
            else {
                if(det(ch[Mid+1]-ch[1],A-ch[1])<=0&&det(ch[Mid+1]-ch[Mid],A-ch[Mid])>=0)
                    return true;
                L=Mid+1;
            }
        }
        return false;
    }
    int main()
    {
        while(~scanf("%d",&N)&&N){
            rep(i,1,N) scanf("%lld %lld",&a[i].x,&a[i].y);
            convex();  ans=0;
            scanf("%d",&Q);
            rep(i,1,Q) {
                point fcy;
                scanf("%lld %lld",&fcy.x,&fcy.y);
                if(check(fcy)) ans++;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }

    上下凸包代码:不知道咋的,一直wa1,也有可能是思路有问题吧,日后再补。

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=100010;
    struct point{
        ll x,y;
        point(){}
        point(ll xx,ll yy):x(xx),y(yy){}
    };
    ll dot(point w,point v){ return w.x*v.x+w.y*v.y;}
    ll det(point w,point v){ return w.x*v.y-w.y*v.x;}
    point operator -(point w,point v){ return point(w.x-v.x,w.y-v.y);}
    point a[maxn],ch[maxn]; int ttop,top,N,Q,ans;
    bool cmp(point w,point v){
        if(w.x!=v.x) return w.x<v.x; return w.y<v.y;
    }
    void convex()
    {
        top=0;
        sort(a+1,a+N+1,cmp);
        rep(i,1,N) {
            while(top>1&&det(ch[top]-ch[top-1],a[i]-ch[top-1])<=0) top--;
            ch[++top]=a[i];
        }
        ttop=top;
        for(int i=N-1;i>=1;i--){
            while(top>ttop&&det(ch[top]-ch[top-1],a[i]-ch[top-1])<=0) top--;
            ch[++top]=a[i];
        }
    }
    bool check1(point A)
    {
        int L=1,R=ttop-1,Mid;
        while(L<=R){
            Mid=(L+R)>>1;
            if(A.x<ch[Mid].x) R=Mid-1;
            else {
                if(ch[Mid+1].x>=A.x&&det(ch[Mid+1]-ch[Mid],A-ch[Mid])>=0){
                        return true;
                }
                L=Mid+1;
            }
        }
        return false;
    }
    bool check2(point A)
    {
        int L=ttop,R=top-1,Mid;
        while(L<=R){
            Mid=(L+R)>>1;
            if(A.x>ch[Mid].x) R=Mid-1;
            else {
                if(ch[Mid+1].x<=A.x&&det(ch[Mid+1]-ch[Mid],A-ch[Mid])>=0) return true;
                L=Mid+1;
            }
        }
        return false;
    }
    int main()
    {
        while(~scanf("%d",&N)&&N){
            rep(i,1,N) scanf("%lld %lld",&a[i].x,&a[i].y);
            convex();  ans=0;
            scanf("%d",&Q);
            rep(i,1,Q) {
                point fcy;
                scanf("%lld %lld",&fcy.x,&fcy.y);
                if(check1(fcy)&&check2(fcy)) ans++;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    问题2017S03
    问题2017S02
    高等代数问题1
    无穷积分换元法的严格解释
    线性空间的同构理论
    问题2017S01
    朴素贝叶斯分类
    决策树
    温习MATLAB
    感知机
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10998631.html
Copyright © 2011-2022 走看看