• ZOJ1081:Points Within——题解


    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1081

    题目大意:给定一个点数为 n 的多边形,点按照顺序给出,再给出 m 个点,询问每个点是否在多边形内。

    ——————————————————————————————

    计算几何开荒期,所以都算是板子吧……既然是板子那么题解自然也都是集网上之大成。

    所以以后也就不多说了。正式往下看题解吧。

    ——————————————————————————————

    这是一道求点是否在一个多边形内的题。

    对这道题我们有两种算法,第二种太麻烦了就不讲了。

    第一种为射线法:即我们有一个点,向左(右)水平做一道射线,求出射线与四边形交点个数,如果个数为奇数则在这里面。

    但是如果交在线段端点上时我们需要规定交在边的下端点统计进答案或是交在边的上端点统计进答案(也就是保证一个点要么都被统计要么都不被统计)。

    判断端点序号的坐标上下关系用叉乘,顺便可以判断该点是否在边上。

    #include<cstdio>
    #include<queue>
    #include<cctype>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int M=500010;
    const int N=1000010;
    const int INF=10*N;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    struct point{//既是向量又是点
        int x;
        int y;
    }q[N],p;
    int n,m,cnt;
    inline point getmag(point a,point b){
        point s;
        s.x=b.x-a.x;s.y=b.y-a.y;
        return s;
    }
    inline int multiX(point a,point b){
        return a.x*b.y-b.x*a.y;
    }
    inline int multiP(point a,point b){
        return a.x*b.x+a.y*b.y;
    }
    bool pan(){
        int sum=0;
        for(int i=1;i<=n;i++){
        int d=multiX(getmag(p,q[i]),getmag(p,q[i%n+1]));
        if(!d){//三点共线
            if(multiP(getmag(p,q[i]),getmag(p,q[i%n+1]))<=0)return 1;//是否在线段上
        }
        int d1=q[i].y-p.y;
        int d2=q[i%n+1].y-p.y;
        if(d>0&&d1>=0&&d2<0)sum++;
        if(d<0&&d1<0&&d2>=0)sum++;
        }
        if(sum%2)return 1;
        return 0;
    }
    int main(){
        while(scanf("%d",&n)!=EOF&&n){
        m=read();
        cnt++;
        if(cnt!=1)putchar('
    ');
        for(int i=1;i<=n;i++){
            q[i].x=read();
            q[i].y=read();
        }
        printf("Problem %d:
    ",cnt);
        for(int i=1;i<=m;i++){
            p.x=read();
            p.y=read();
            if(pan())puts("Within");
            else puts("Outside");
        }
        }
        return 0;
    }
  • 相关阅读:
    POJ 1860 Currency Exchange (Bellman ford)
    POJ 1502 MPI Maelstrom (最短路)
    2015 Multi-University Training Contest 2 1006(DFS)
    HDU 1495 非常可乐(枚举+DFS)
    HDU 5289 Assignment(单调队列)
    ACDream 1734 Can you make a water problem?(贪心)
    ACDream 1735 输油管道
    ACDream 1726 A Math game (折半查找)
    CSU 1602 Needle Throwing Game (投针问题)
    CSU 1604 SunnyPig (BFS)
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/8051615.html
Copyright © 2020-2023  润新知