热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ACM计算几何之Cupid'sArrow——hdu1756

ACM计算几何Cupid'sArrowhdu1756点在多边形内射

Cupid‘s Arrow

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

Problem Description

传说世上有一支丘比特的箭,凡是被这支箭射到的人,就会深深的爱上射箭的人。
世上无数人都曾经梦想得到这支箭。Lele当然也不例外。不过他想,在得到这支箭前,他总得先学会射箭。
日子一天天地过,Lele的箭术也越来越强,渐渐得,他不再满足于去射那圆形的靶子,他开始设计各种各样多边形的靶子。
不过,这样又出现了新的问题,由于长时间地练习射箭,Lele的视力已经高度近视,他现在甚至无法判断他的箭射到了靶子没有。所以他现在只能求助于聪明的Acmers,你能帮帮他嘛?
Input
本题目包含多组测试,请处理到文件结束。
在每组测试的第一行,包含一个正整数N(2接着N行按顺时针方向给出这N个顶点的x和y坐标(0然后有一个正整数M,表示Lele射的箭的数目。
接下来M行分别给出Lele射的这些箭的X,Y坐标(0Output
对于每枝箭,如果Lele射中了靶子,就在一行里面输出"Yes",否则输出"No"。
Sample Input
4
10 10
20 10
20 5
10 5
2
15 8
25 8
Sample Output
Yes

No


这道题也是判断点是否在多边形内,这次来说一下射线法。。

之前说了一个O(logn)的二分法,详情可戳:http://blog.csdn.net/lttree/article/details/24291719

射线法:

bubuko.com,布布扣

这张图片比较全啊。

我们以所求点为原点向任意方向做一条射线,如果点在多边形内,做的射线肯定会与多边形的某条边相交。(如a所示),因为多边形可能为凹多边形,所以如果交点有一个则为点在多边形内,若有2个交点则点在多边形外。

以此类推,奇数个点代表点在多边形内,偶数个点代表点在多边形外。

但是还是有几个特殊情况要处理一下:

①射线经过的是多边形端点,如图b

②射线经过多边形某条边,如图c

③射线经过多边形端点和边,如图d

④射线经过端点且边,如图e

我们的解决方法:(序号顺序并非解决相应问题方法)

①对于多边形平行边,不考虑它。

②对于多边形的顶点和射线相交的情况,如果该顶点是其所属边上纵坐标较大的顶点,则计数,否则,忽略该点。

③对于所求的点在多边形边上的情况,直接判断点属于多边形。

And now 让我们一起AC~

PS:不要忘了精度问题哈~


#include
#define MAX 100001
// 需要精度判断
#define EPS 1e-8
struct point
{
double x,y;
}p[MAX];
// 比较大小函数
double Max(double a,double b) { return a>b?a:b; }
double Min(double a,double b) { return a>b?b:a; }
double abs(double a) { return a<0?-a:a; }
// 两个向量的叉积
double cross(double x,double y,double xx,double yy)
{
return x*yy-y*xx;
}
// 判断点是否在直线上,叉积为0,且满足坐标相对位置条件
bool online(point a,point b,point c)
{
if( abs( cross(a.x-b.x,a.y-b.y,c.x-b.x,c.y-b.y) ) a.x>=Min(b.x,c.x) && a.x<=Max(b.x,c.x) &&
a.y>=Min(b.y,c.y) && a.y<=Max(b.y,c.y) )
return 1;
return 0;
}
int main()
{
int i,n,m,js,flag;
point a,b,c,d;
while( scanf("%d",&n)!=EOF )
{
// 先输入多边形各个点(此题按顺时针输入
for(i=0;i scanf("%lf%lf",&p[i].x,&p[i].y);
scanf("%d",&m);
while(m--)
{
flag=js=0;
// 输入所求点坐标
scanf("%lf%lf",&a.x,&a.y);
b.x=-100,b.y=a.y;
for(i=0; i {
c.x=p[i].x;
c.y=p[i].y;
d.x=p[ (i+1)%n ].x;
d.y=p[ (i+1)%n ].y;
// 判断点是否在线上
if(online(a,c,d))
{
flag=1;
break;
}
// 第一个判断:是否平行边,后面两个a点纵坐标在两端点之间,而且<=最大的端点(因为解决方法中②)
// 第二个判断为判断线段相交,注意精度判定
if( c.y!=d.y && a.y>Min(c.y,d.y) && a.y<=Max(c.y,d.y) )
if( cross(a.x-d.x,a.y-d.y,c.x-d.x,c.y-d.y)*cross(b.x-d.x,b.y-d.y,c.x-d.x,c.y-d.y) ++js;
}
// 判断交点奇偶
if(js&1) flag=1;
if(flag) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}

ACM-计算几何之Cupid&#39;s Arrow——hdu1756,布布扣,bubuko.com


推荐阅读
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文介绍了一种轻巧方便的工具——集算器,通过使用集算器可以将文本日志变成结构化数据,然后可以使用SQL式查询。集算器利用集算语言的优点,将日志内容结构化为数据表结构,SPL支持直接对结构化的文件进行SQL查询,不再需要安装配置第三方数据库软件。本文还详细介绍了具体的实施过程。 ... [详细]
  • 实现一个通讯录系统,可添加、删除、修改、查找、显示、清空、排序通讯录信息
    本文介绍了如何实现一个通讯录系统,该系统可以实现添加、删除、修改、查找、显示、清空、排序通讯录信息的功能。通过定义结构体LINK和PEOPLE来存储通讯录信息,使用相关函数来实现各项功能。详细介绍了每个功能的实现方法。 ... [详细]
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • 1.RoIPoolingRoIPooling顾名思义对Roi进行Pooling操作,主要用于目标检测任务。RoI(Regionofinterest&# ... [详细]
author-avatar
Hcl
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有