凸多边形

Time Limit: 2000 MS    Memory Limit: 65536 K

Total Submit: 130(24 users)   Total Accepted: 40(18 users)       Rating:         Special Judge: No

Description

已知一个凸多边形A(包含n个点,点按照顺时针给出),和一个点集B(包含m个点),请判断这m个点是否都严格在凸多边形A内部。

Input

输入包含多组测试数据。

对于每组测试数据:

第1行,包含一个整数n (3 ≤ n ≤ 105)代表着凸多边形A的点的数量。

接下来n行每行包含一个坐标(x, y) (-109 ≤ x, y ≤ 109) 表示这个凸多边形,点按照顺时针给出。

第n + 2行,包含一个整数m (3 ≤ m ≤ 105)代表着点集B的点的数量。

接下来m行每行包含一个坐标(x, y) (-109 ≤ x, y ≤ 109) 表示这个点集B。

处理到文件结束

Output

对于每组测试数据:

第1行,如果点集B都严格在凸多边形A内,输出YES,否则输出NO。

Sample Input

4

-10 -10

-10 10

10 10

10 -10

3

0 0

1 1

2 2

4

-10 -10

-10 10

10 10

10 -10

3

100 100

1 1

2 2

Sample Output

YES

NO

Author

齐达拉图@HRBUST


  计算几何,判断点是否在多边形内(二分法)。

  判断点是否在多边形内有多种方法,例如:射线法,角度和判断法,弧长法,二分法。

  射线法是我最开始学的方法,较麻烦;角度和判断法也叫转角法,比较方便,但是由于要计算大量的反三角函数,所以速度较慢,容易产生精度误差。而弧长法的优点恰恰就是精度高,只需作乘法和减法,若对整数坐标则完全没有精度问题。而且实现简单,比射线法和转角法都好写。二分法速度最快,特别适应于判断多个点是否在多边形内的情况。就像这道题。

  其中前三种方法时间复杂度都是O(n),二分法时间复杂度是O(logn)。

  这道题的题意是已知构成凸多边形A的n个点的坐标,和点集B的m个点的坐标,求这B的m个点是否都在凸多边形A内(严格内部,就是点不能在多边形边上)。

  思路:用以上前三种方法的任意一种都会超时,时间复杂度为(O(mn)),遂使用二分法,这道题的时间复杂度为(O(mlogn))。

  二分法求多边形的步骤:

  1、选择多边形其中一个点为起点,连接其它点作射线。

  2、判断给定的点是否在所有射线包围的区域之内,即判断给定点是否在最左侧射线的左边,或者在最右侧射线的右边。

  3、如果在射线包围的区域之内,选择构成最两侧的射线的点为left和right,则mid = (left+right)/2,连接给顶点和起点作射线,判断该射线在mid点和起点的哪一边,不断循环,如此用二分法最后求出给定点所在的三角形区域,由此确定了除起点外的一条边。

  4、判断给定点在这条边的左方还是右方,由此判断给定点是否在三角形区域内,也就是是否在多边形内。

  注意:这道题有个坑,点要求严格在多边形内部,也就是说不能在多边形的边上。注意这一点,测试数据控制的很严格,WA了好多次才明白过来。

  代码:

 #include <stdio.h>
#define eps 1e-10
struct Point{
double x,y;
};
double xmulti(Point p1,Point p2,Point p0) //求p1p0和p2p0的叉积,如果大于0,则p1在p2的顺时针方向
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
Point A[],B[];
int main()
{
int i,n,m;
while(scanf("%d",&n)!=EOF){
for(i=;i<=n;i++) //输入多边形的顶点
scanf("%lf%lf",&A[i].x,&A[i].y);
scanf("%d",&m);
for(i=;i<=m;i++) //输入点集
scanf("%lf%lf",&B[i].x,&B[i].y);
//二分法判断B上的点是否在原凸多边形A内,注意在边上不行
for(i=;i<=m;i++){ //B[i]
if(xmulti(B[i],A[],A[])<=eps || xmulti(B[i],A[n],A[])>=-eps) //在第一个点为起点的扇形之外或在边上
break;
int left=,right=n;
while(right-left!=){
int mid = (left+right)/;
if(xmulti(B[i],A[mid],A[])>eps)
left = mid;
else
right = mid;
}
if(xmulti(B[i],A[right],A[left])<=eps) //在边之外或在边上
break;
}
if(i>m)
printf("YES\n");
else
printf("NO\n");
}
return ;
}

Freecode : www.cnblogs.com/yym2013

hrbustoj 1429:凸多边形(计算几何,判断点是否在多边形内,二分法)的更多相关文章

  1. HDU - 4458 计算几何判断点是否在多边形内

    思路:将飞机看成不动的,然后枚举时间看点是否在多边形内部. #include<bits/stdc++.h> #define LL long long #define fi first #d ...

  2. hrbustoj 1306:再遇攻击(计算几何,判断点是否在多边形内,水题)

    再遇攻击 Time Limit: 1000 MS    Memory Limit: 65536 K Total Submit: 253(37 users)   Total Accepted: 56(2 ...

  3. zoj 1081:Points Within(计算几何,判断点是否在多边形内,经典题)

    Points Within Time Limit: 2 Seconds      Memory Limit: 65536 KB Statement of the Problem Several dra ...

  4. POJ 1584 A Round Peg in a Ground Hole 判断凸多边形 点到线段距离 点在多边形内

    首先判断是不是凸多边形 然后判断圆是否在凸多边形内 不知道给出的点是顺时针还是逆时针,所以用判断是否在多边形内的模板,不用是否在凸多边形内的模板 POJ 1584 A Round Peg in a G ...

  5. 百度地图 判断marker是否在多边形内

    昨天画了圆形,判marker是否存在圆形内.今天来画多边形,判断marker在多边形内. 需要引入一个js      <script type="text/javascript&quo ...

  6. C# 判断点是否在多边形内

    /// <summary>/// 判断点是否在多边形内/// </summary>/// <param name="pnt">点</par ...

  7. [zoj] 1081 Points Within || 判断点是否在多边形内

    原题 多组数据. n为多边形顶点数,m为要判断的点数 按逆时针序给出多边形的点,判断点是否在多边形内,在的话输出"Within",否则输出"Outside" / ...

  8. PHP 判断点是否在多边形内

    如何判断一个点是否在一个多边形内,何时会用到这个场景. 我们就模拟一个真是场景.我们公司是快递公司,在本地区域有6个分点.每个分点有3-5个工人负责附近的快递派遣发送,所以根据每个点的服务区域我们就能 ...

  9. Hrbustoj 1429 二分+计算几何

    http://www.bubuko.com/infodetail-1121744.html 在这个上面学习了方法 如果要判断巨量的点 就应该使用二分法 思路是先从a[1] a[n] a[2]来判断是否 ...

随机推荐

  1. hdu 2084 数塔(动态规划)

    本题是一个经典的动态规划题. 直接利用记忆化搜索:见图解 Ac code : #include<stdio.h> #include<string.h> #define max( ...

  2. 二、Ubuntu14.04下安装Hadoop2.4.0 (伪分布模式)

    在Ubuntu14.04下安装Hadoop2.4.0 (单机模式)基础上配置 一.配置core-site.xml /usr/local/hadoop/etc/hadoop/core-site.xml ...

  3. html中input输入框屏蔽鼠标右键

    <label> <input id="ckdestinationId" type="text" oncontextmenu="ret ...

  4. javafx实现饼图统计效果图

  5. U盘10分钟安装linux系统

    说来可能不信,10分钟包括创建U盘启动盘,用U盘启动,安装,不联网,不更新,不安装语言包,等装好系统再更新. Windows系统硬盘分区 如果你用的是Windows系统,现有的硬盘没有未分配的空间,需 ...

  6. javaScript模块化规范ADM与CMD

    模块化:模块化是指在解决某一个复杂问题时,依照一种分类的思维把问题进行系统性的分解处理,可以想象一个巨大的系统代码,被整合优化分割成逻辑性很强的模块时,对于软件是一种何等意义的存在. 模块化系统所必须 ...

  7. iOS工程如何支持64-bit(转)

    苹果在2014年10月20号发布了一条消息:从明年的二月一号开始,提交到App Store的应用必须支持64-bit.详细消息地址为:https://developer.apple.com/news/ ...

  8. java web dao 层和dao 实现层有什么好处

    接口是为了屏蔽不同数据库的JDBC实现差异而出现的. 以常见的系统组织结构为例,管理系统里有一个部门department表用于存放部门信息,因为部门下面可能有子部门所以表中的字段要定义成类似树形结构的 ...

  9. 探讨关于C#中Foreach的本质

    一.为什么数组和集合可以使用foreach遍历 01. 因为数组和集合都实现了IEnumerable接口,该接口中只有一个方法,GetEnumerator() 02.数组类型是从抽象基类型 Array ...

  10. java笔记--异常详解与处理

    一.异常概念 Throwable类是Java中所有错误或异常的超类. 1.只有当对象是此类(或其子类)的实例时,才能通过Java虚拟机或着Java throw语句抛出.     2.只有此类或其子类才 ...