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

Cupid's Arrow

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3105    Accepted Submission(s): 1103


Problem Description
传说世上有一支丘比特的箭,凡是被这支箭射到的人,就会深深的爱上射箭的人。
世上无数人都曾经梦想得到这支箭。Lele当然也不例外。不过他想,在得到这支箭前,他总得先学会射箭。
日子一天天地过,Lele的箭术也越来越强,渐渐得,他不再满足于去射那圆形的靶子,他开始设计各种各样多边形的靶子。
不过,这样又出现了新的问题,由于长时间地练习射箭,Lele的视力已经高度近视,他现在甚至无法判断他的箭射到了靶子没有。所以他现在只能求助于聪明的Acmers,你能帮帮他嘛?
 
Input
本题目包含多组测试,请处理到文件结束。
在每组测试的第一行,包含一个正整数N(2<N<100),表示靶子的顶点数。
接着N行按顺时针方向给出这N个顶点的x和y坐标(0<x,y<1000)。
然后有一个正整数M,表示Lele射的箭的数目。
接下来M行分别给出Lele射的这些箭的X,Y坐标(0<X,Y<1000)。
 
Output
对于每枝箭,如果Lele射中了靶子,就在一行里面输出"Yes",否则输出"No"。
 
Sample Input
4
10 10
20 10
20 5
10 5
2
15 8
25 8
 
Sample Output
Yes
No
 
AC代码:
 1 /**
 2     Finished time:9.15.2018
 3     Author:hyacinth
 4     Algorithm:计算几何判断点是否在多边形内
 5 */
 6 #include<iostream>
 7 #include<cstdio>
 8 #include<cmath>
 9 using namespace std;
10 const double esp=1e-8;
11 
12 struct point
13 {
14     double x,y;
15 };
16 point p[105];
17 int n,m;
18 
19 double k(point p1,point p2)//斜率
20 {
21     return (p2.y-p1.y)/(p2.x-p1.x);
22 }
23 bool onEdge(point q,point p1,point p2)//判断q是否在p1p2上
24 {
25     if(q.x >= min(p1.x,p2.x) && q.x <= max(p1.x,p2.x))//去除q在p1p2延长线上的情况
26         if(fabs(k(q,p1)-k(p2,p1)) <= esp)//通过斜率是否相等来判断q是否在p1p2上
27             return true;
28     return false;
29 }
30 bool inPolaygon(point q)
31 {
32     int cnt=0;
33     point p1,p2;
34     p1=p[0];
35     for(int i=1;i <= n;++i)
36     {
37         p2=p[i%n];
38         if(onEdge(q,p1,p2))
39             return true;
40         if(p1.y != p2.y){//判断p1p2是否为水平边,水平边不作考虑
41             if(q.y > min(p1.y,p2.y) && q.y <= max(p1.y,p2.y) && q.x <= max(p1.x,p2.x)){//注意:此处q.y是严格>min(),此处是用来处理射线与顶点相交的情况的,当相交的顶点为凸顶点时,两条边都加上,当相交的顶点是凹顶点时,只加右边那条边
42                 if(p1.x == p2.x)//当p1p2为竖线时,由条件q.x <= max(p1.x,p2.x)可得由p向右发出的射线与p1p2有交点
43                     cnt++;
44                 else{
45                     double x=p1.x+(q.y-p1.y)/k(p2,p1);//x : 经过q点且平行于x轴的直线与p1p2交点的横坐标
46                     cnt += (q.x <= x ? 1:0);//如果q.x <= x,说明q向右发出的射线与p1p2有交点
47                 }
48             }
49         }
50         p1=p2;
51     }
52     return cnt&1;
53 }
54 
55 int main()
56 {
57     while(~scanf("%d",&n))
58     {
59         for(int i=0;i < n;++i)
60             scanf("%lf%lf",&p[i].x,&p[i].y);
61         scanf("%d",&m);
62         for(int i=1;i <= m;++i)
63         {
64             point q;
65             scanf("%lf%lf",&q.x,&q.y);
66             if(inPolaygon(q))
67                 printf("Yes\n");
68             else
69                 printf("No\n");
70         }
71     }
72     return 0;
73 }
View Code

猜你喜欢

转载自www.cnblogs.com/violet-acmer/p/9651799.html
今日推荐