• ZOJ 1081 Points Within | 判断点在多边形内


    题目:

    给个n个点的多边形,n个点按顺序给出,给个点m,判断m在不在多边形内部


    题解:

    网上有两种方法,这里写一种:射线法

    大体的思想是:以这个点为端点,做一条平行与x轴的射线(代码中射线指向x轴正方向)

    如果交点个数为奇数的话就在内部,如果为偶数(包括0)就在外部

     

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define N 105
    using namespace std;
    int n,m;
    struct point//点(向量的结构体)
    {
        int x,y;
        point() {}//初始化
        point (int _x,int _y) :
    	x(_x),y(_y) {};//用一对坐标初始化点
        inline point operator + (const point &rhs) const//向量加法
    	{
    	    return point(x+rhs.x,y+rhs.y);
    	}
        inline point operator - (const point &rhs) const//向量减法
    	{
    	    return point(x-rhs.x,y-rhs.y);
    	}
        inline int operator * (const point &rhs) const//向量叉乘
    //向量叉乘的几何意义是以两个向量为邻边的平行四边形的有向面积 也就是|a|*|b|*sin<a,b> 这里的sin<a,b>决定了
    //如果a,b是逆时针的,那么sin<a,b>大于0,有向面积大于0,反之<0 
    	{
    	    return x*rhs.y-y*rhs.x;
    	}
        friend inline int dot(const point &lhs,const point &rhs)//向量点乘
    	{
    	    return lhs.x*rhs.x+lhs.y*rhs.y;
    	}
    }q;
    inline int check(const point &u,const point &v,const point &p)//判断点是不是在线段上
    //u,v是线段端点,p是点
    {
        int det=(u-p)*(v-p);//如果向量(u-p)*(v-p)==0就说明u,v,p共线(因为没面积)
        if (det!=0) return 0;
        int Dot=dot(u-p,v-p);//如果(u-p)点乘(v-p)<=0 就说明点在线段上
        return Dot<=0;
    }
    struct polygon//多边形结构体
    {
        int n;
        point p[N];
        void init(int _n)
    	{
    	    n=_n;
    	    for (int i=0;i<n;i++)
    	    	scanf("%d%d",&p[i].x,&p[i].y);
    	    p[n]=p[0];
    	    if (Area()<0) reverse(p,p+n);//通过判断多边形的有向面积来把点规范成逆时针的
    	    p[n]=p[0];
    	}
        inline int Area() const
        //计算多边形的有向面积(如果点是逆时针的话就是正的,否则是负的)
    	{
    	    int ret=0;
    	    for (int i=0;i<n;i++)
    		    ret+=p[i]*p[i+1];
    	    return ret=0;
    	}
        bool inner (const point &q)//判断点是不是在多边形内部
    	{
    	    int cnt=0;
    	    for (int i=0;i<n;i++)
    	    {
    		    if (check(p[i],p[i+1],q)) return 1;//如果点在线段上显然可以
    		    int d1=p[i].y-q.y,d2=p[i+1].y-q.y;
    		    int det=(p[i]-q)*(p[i+1]-q);
    		    if ( (det>=0 && d1<0 && d2>=0) ||    
    		         (det<=0 && d1>=0 && d2<0)) ++cnt;//第一个条件是判断p在多边形内的时候,第二个是判断p在多边形外的时候
    	    }
    	    return cnt&1;
    	}
    }P;
        
    int main()
    {
        for (int tt=1;;tt++)
        {
    	    scanf("%d",&n);
    	    if (n==0) break;
    	    scanf("%d",&m);
    	    P.init(n);
    	    if (tt!=1)
    	        putchar('
    ');
    	    printf("Problem %d:
    ",tt);
    	    while (m--)
    	    {
    	        scanf("%d%d",&q.x,&q.y);
    	        if (P.inner(q)) puts("Within");
    	        else puts("Outside");
    	    }
        }
        return 0;
    }
    
  • 相关阅读:
    算法作业10——0-1装载问题(背包问题)
    算法作业9-1——最长公共子序列问题
    算法作业9-2——背包问题
    算法作业7——投资问题
    算法作业6——选第k小的元素:特定分治策略
    【Java并发编程】并发编程大合集
    Redis学习笔记-Redis内部数据结构
    近期的随笔
    2013年的总结,比以往时候来得晚了一些
    探索推荐引擎内部的秘密,第 3 部分: 深入推荐引擎相关算法
  • 原文地址:https://www.cnblogs.com/mrsheep/p/7994234.html
Copyright © 2020-2023  润新知