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 }

参考资料:http://makaidong.com/WArobot/6071_1226646.html

原文地址:https://www.cnblogs.com/violet-acmer/p/9651799.html

时间: 2024-08-13 10:53:44

hdu 1756(判断点是否在多边形中)的相关文章

HDU 1756 Cupid&#39;s Arrow 判断点在多边形的内部

Cupid's Arrow Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1163    Accepted Submission(s): 425 Problem Description 传说世上有一支丘比特的箭,凡是被这支箭射到的人,就会深深的爱上射箭的人.世上无数人都曾经梦想得到这支箭.Lele当然也不例外.不过他想,在得到这支箭前,

HDU 1756 Cupid&#39;s Arrow(点在多边形内判定)

Problem Description 传说世上有一支丘比特的箭,凡是被这支箭射到的人,就会深深的爱上射箭的人. 世上无数人都曾经梦想得到这支箭.Lele当然也不例外.不过他想,在得到这支箭前,他总得先学会射箭. 日子一天天地过,Lele的箭术也越来越强,渐渐得,他不再满足于去射那圆形的靶子,他开始设计各种各样多边形的靶子. 不过,这样又出现了新的问题,由于长时间地练习射箭,Lele的视力已经高度近视,他现在甚至无法判断他的箭射到了靶子没有.所以他现在只能求助于聪明的Acmers,你能帮帮他嘛?

HDU 1756 Cupid&#39;s Arrow (几何问题,判定点在多边形内部)

题意:中文的么,自己看喽. 析:很容易明白是判定点是不是在多边形内部,一般是向量来判定,我一开始用点在向量的右侧,因为是顺时针给的,只要点全在外侧或边上, 就可以,暴力一下就ok.由于这个是浮点数,一定要注意精度,也就是误差,结果WA了好几次,一气之下,我改了算法,采用转角法, 假想有一条向右的射线,统计多边形穿过这条射线正反多少次,顺时针减1,逆时针加1.一定要注意这个精度控制,不然就WA. 代码如下: #include <iostream> #include <cstdio>

判断点是否在多边形内部

转自阿凡卢原文 判断点是否在多边形内部 如何判断一个点是否在多边形内部? (1)面积和判别法:判断目标点与多边形的每条边组成的三角形面积和是否等于该多边形,相等则在多边形内部. (2)夹角和判别法:判断目标点与所有边的夹角和是否为360度,为360度则在多边形内部. (3)引射线法:从目标点出发引一条射线,看这条射线和多边形所有边的交点数目.如果有奇数个交点,则说明在内部,如果有偶数个交点,则说明在外部. 具体做法:将测试点的Y坐标与多边形的每一个点进行比较,会得到一个测试点所在的行与多边形边的

判断点是否在多边形内

有一个n边形,顶点为p1,p2,...,pn;给定一个已知点p,判断p在此多边形内还是外. 预备知识: 两线段相交的定义,如果一条线段的两端分别处在另一条线段的两端,则此两线段相交 判断2点在线段的两侧可以用向量的叉乘实现! 基本步骤: 1,过p点垂直向上作一条射线 2,判断此射线与n边形n条边的交点 3,把所有交点相加,如果是奇数则说明在多边形内,否则在多边形外 思路非常的简单,另外说明一下几种特殊的情况: 1,射线与多边形的顶点相交:比如射线过多边形的Pi点,则如果Pi-1和Pi+1在此射线

HDU 3982 半平面交+圆与多边形面积交

Harry Potter and J.K.Rowling Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 685    Accepted Submission(s): 210 Problem Description In July 31st, last month, the author of the famous novel seri

hlg1306再遇攻击--射线法判断点是否在多边形内部

再遇攻击 Time Limit: 1000 MS Memory Limit: 65536 K Total Submit: 313(40 users) Total Accepted: 91(32 users) Rating:  Special Judge: No Description Dota中英雄技能攻击会有一个范围,现在释放一个技能给出他的攻击范围和目标英雄的位置,问是否能攻击到.攻击范围保证是一个多边型. Input 有多组测试数据 第一行输入1个整数n, 期中n代表攻击范围是给出的n个点

hdu 4587 判断孤立点+割点+ 删除点之后,剩下多少连通分量

做了很久...... 题目链接:  http://acm.hdu.edu.cn/showproblem.php?pid=4587 先枚举删除的第一个点,第二个点就是找割点,没有割点当然也有答案 学到的: 1.图论硬套模板不太现实,比如这道题,我能想到孤立点是特殊情况,删除孤立点,连通分支个数会减少一,但是一直处理不好,最后按缩点的做法搞了, 判断是不是孤立点的方法: 就是先用一个数组scnt[i]=j,vv[j]++  表示点i在以j为祖先的联通分支里,而且每次都让vv[j]++,就使得vv[j

判断JSON返回的对象中的firstName这一列的值是否包含指定的字符

判断JSON返回的对象中的firstName这一列的值是否包含指定的字符,如果包含指定字符则返回true,否则返回false 标签: <无> 代码片段(1)[全屏查看所有代码] 1. [代码][其他]代码 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51