HDU 1756 点在多边形内 Cupid's Arrow

来源:互联网 发布:淘宝哪些店铺衣服好看 编辑:程序博客网 时间:2024/06/08 18:00

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1756

分析:[射线法]

          从已知点向x+oo远处向一水平射线,判断射线与多边形的交点个数,

          若为偶数,则点在多边形外,反之则在多边形内。

          注意几种特殊情况:

                 1、边和射线共线;

                 2、边的端点在射线上(上、下两端点只能考虑一个)

#include<iostream>#include<string>#include<cstring>#include<algorithm>#include<cstdio>#include<cmath>#include<iomanip>using namespace std;const int maxn=100000;const int inf = 0xFFFFFFF;int n;struct point{    double x,y;    void read(){        scanf("%lf%lf",&x,&y);    }}f[maxn];struct segment {    point a;    point b;}seg;double cross(point A,point B,point C){///叉积    return (B.x-A.x)*(C.y-A.y)-(C.x-A.x)*(B.y-A.y);}bool Dot_Segment(point D,segment R){ ///点在线段上    if(D.x<min(R.a.x,R.b.x)||D.x>max(R.a.x,R.b.x)||       D.y<min(R.a.y,R.b.y)||D.y>max(R.a.y,R.b.y))        return false;    if(cross(R.a,R.b,D))        return false;    return true;}bool Segmentcrossing(segment R,segment T){///线段相交    return (cross(R.a,R.b,T.a)*cross(R.a,R.b,T.b)<0&&            cross(T.a,T.b,R.a)*cross(T.a,T.b,R.b)<0);}bool work(point D){    point M;    M.x=inf;    M.y=D.y;    seg.a=D;    seg.b=M;    int num=0;    for(int i=1;i<=n;++i){        segment R;        R.a=f[i]; R.b=f[i+1];        if(Dot_Segment(D,R))///点在边上            return true;        if(cross(R.a,R.b,D)==0)///边和射线平行,即边水平            continue;        if(Dot_Segment(R.a,seg)){///边的上端点在射线上            if(R.a.y>R.b.y) num++;        }        else if(Dot_Segment(R.b,seg)){            if(R.a.y<R.b.y) num++;        }        else if(Segmentcrossing(R,seg))///射线和边相交            num++;    }    return num%2;}int main(){    while(~scanf("%d",&n)){        for(int i=1;i<=n;++i)            f[i].read();        f[n+1]=f[1];        int m;        scanf("%d",&m);        while(m--){            point D; D.read();            if(work(D)) puts("Yes");            else        puts("No");        }    }    return 0;}


原创粉丝点击