HDOJ 1756 Cupid's Arrow

          今天还是在看计算几何,原来计算几何一直有点差,不过今天这道题一交就过,我都惊讶了。题目是中文题很容易理解,就是判断一点是否在多边形内。判断点在多边形内有好几种方法,我这里用的是 射线法+微移,我原来以为真的要移动,看了学长借给我的 刘汝佳《算法艺术》,之后对这种方法有了比较深刻的认识。

http://blog.csdn.net/aacm1992/article/details/7747483

这道题没什么陷阱,硬要算的话就是:点在多边形的边上也算是中了靶的。

代码:

#include<iostream>
#include<cmath>
using namespace std;
#define exp 1e-8
struct Point
{
       double x,y;
} pt[105],p;
int n;
int Cross(Point a,Point b,Point c)
{
    double t=(b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y); 
    //printf("%.3lf\n",t);
    if( fabs(t)<exp)
        return 0;
    return ( t>0? 1:-1 );
}
bool Judge(Point a,Point b,Point c)
{
    if( a.y>=min(b.y,c.y)&&a.y<=max(b.y,c.y))
        return true;
    return false;
}
int cmp(double a,double b)
{
    double t=a-b;
    if( fabs(t)<exp)
        return 0;
    return ( t>0? 1:-1);
}
bool Inpolygon()
{
     int i,cnt;
     Point a,b;
     cnt=0;
     for( i=0; i<n; i++){
          a=pt[i];
          b=pt[(i+1)%n];
          if( a.y<b.y){  //a存储线段高点 b存储线段低点 
              Point temp=a;
              a=b;
              b=temp;
          }
          int flag=Cross(p,b,a);
          if( !flag&&Judge(p,a,b))
              return true;
          if( flag>0 && cmp(a.y,p.y)==1 && cmp(b.y,p.y)<=0)//判断P是否在高点下方 或者在地点上或低点上方。
              cnt++;
     }
     if( cnt%2)
         return true;
     return false;
}

int main()
{
    int m,i;
    double x,y;
    while( scanf("%d",&n)!=EOF){
           for( i=0; i<n; i++)
                scanf("%lf%lf",&pt[i].x,&pt[i].y);
           scanf("%d",&m);
           while( m--){
                  scanf("%lf%lf",&p.x,&p.y);
                  if( Inpolygon())
                      printf("Yes\n");
                  else
                      printf("No\n");
           }
    }
    return 0;
}






你可能感兴趣的:(HDOJ 1756 Cupid's Arrow)