hdu 1756(判断点是否在多边形中)

传送门

 

题解:

  射线法判定点是否在多边形内部;

AC代码:

  

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 using namespace std;
 5 const double esp=1e-8;
 6 const int maxn=100+50;
 7 
 8 int n,m;
 9 struct Point
10 {
11     double x,y;
12 }p[maxn];
13 
14 double K(Point p1,Point p2)
15 {
16     return (p2.y-p1.y)/(p2.x-p1.x);
17 }
18 bool onEdge(Point q,Point p1,Point p2)
19 {
20     if(p1.x == p2.x)//斜率不存在的情况,HDU的数据里没有卡这种情况
21         return q.y >= min(p1.y,p2.y) && q.y <= max(p1.y,p2.y) && q.x == p1.x ? true:false;
22 
23     if(q.x >= min(p1.x,p2.x) && q.x <= max(p1.x,p2.x) && q.y >= min(p1.y,p2.y) && q.y <= max(p1.y,p2.y))
24         return fabs(K(p1,q)-K(p1,p2)) < esp ? true:false;
25     return false;
26 }
27 bool inPolygon(Point q)
28 {
29     int ans=0;
30     Point p1,p2;
31     p1=p[0];
32     for(int i=1;i <= n;++i)
33     {
34         p2=p[i%n];
35         if(onEdge(q,p1,p2))
36             return true;
37         if(p1.y == p2.y)//判断p1p2是否为水平边,水平边不作考虑
38         {
39             p1=p2;//起初,这儿我并没有加这句话,改了好半天才看到
40             continue;
41         }
42         /**
43             注意:此处q.y是严格>min();
44             此处是用来处理射线与顶点相交的情况的
45             当相交的顶点为凸顶点时,两条边都加上;
46             当相交的顶点是凹顶点时,只加右边那条边;
47         */
48         if(q.y > min(p1.y,p2.y) && q.y <= max(p1.y,p2.y) && q.x <= max(p1.x,p2.x))
49         {
50             //当p1p2为竖线时,由条件q.x <= max(p1.x,p2.x)可得由p向右发出的射线与p1p2有交点
51             if(p1.x == p2.x)
52                 ans++;
53             else
54             {
55                 //x : 经过q点且平行于x轴的直线与p1p2交点的横坐标
56                 double x=p1.x+(q.y-p1.y)/K(p1,p2);
57                 if(q.x <= x)//如果q.x <= x,说明q向右发出的射线与p1p2有交点
58                     ans++;
59             }
60         }
61         p1=p2;
62     }
63     return ans&1;
64 }
65 int main()
66 {
67 //    freopen("C:\\Users\\hyacinthLJP\\Desktop\\in&&out\\HDU\\1756.in","r",stdin);
68     while(~scanf("%d",&n))
69     {
70         for(int i=0;i < n;++i)
71             scanf("%lf%lf",&p[i].x,&p[i].y);
72 
73         scanf("%d",&m);
74         for(int i=1;i <= m;++i)
75         {
76             Point q;
77             scanf("%lf%lf",&q.x,&q.y);
78             if(inPolygon(q))
79                 printf("Yes\n");
80             else
81                 printf("No\n");
82         }
83     }
84     return 0;
85 }

 

posted @ 2018-09-15 18:51  HHHyacinth  阅读(242)  评论(0编辑  收藏  举报