hrbustoj 1429:凸多边形(计算几何,判断点是否在多边形内,二分法)
凸多边形
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:凸多边形(计算几何,判断点是否在多边形内,二分法)的更多相关文章
- HDU - 4458 计算几何判断点是否在多边形内
思路:将飞机看成不动的,然后枚举时间看点是否在多边形内部. #include<bits/stdc++.h> #define LL long long #define fi first #d ...
- hrbustoj 1306:再遇攻击(计算几何,判断点是否在多边形内,水题)
再遇攻击 Time Limit: 1000 MS Memory Limit: 65536 K Total Submit: 253(37 users) Total Accepted: 56(2 ...
- zoj 1081:Points Within(计算几何,判断点是否在多边形内,经典题)
Points Within Time Limit: 2 Seconds Memory Limit: 65536 KB Statement of the Problem Several dra ...
- POJ 1584 A Round Peg in a Ground Hole 判断凸多边形 点到线段距离 点在多边形内
首先判断是不是凸多边形 然后判断圆是否在凸多边形内 不知道给出的点是顺时针还是逆时针,所以用判断是否在多边形内的模板,不用是否在凸多边形内的模板 POJ 1584 A Round Peg in a G ...
- 百度地图 判断marker是否在多边形内
昨天画了圆形,判marker是否存在圆形内.今天来画多边形,判断marker在多边形内. 需要引入一个js <script type="text/javascript&quo ...
- C# 判断点是否在多边形内
/// <summary>/// 判断点是否在多边形内/// </summary>/// <param name="pnt">点</par ...
- [zoj] 1081 Points Within || 判断点是否在多边形内
原题 多组数据. n为多边形顶点数,m为要判断的点数 按逆时针序给出多边形的点,判断点是否在多边形内,在的话输出"Within",否则输出"Outside" / ...
- PHP 判断点是否在多边形内
如何判断一个点是否在一个多边形内,何时会用到这个场景. 我们就模拟一个真是场景.我们公司是快递公司,在本地区域有6个分点.每个分点有3-5个工人负责附近的快递派遣发送,所以根据每个点的服务区域我们就能 ...
- Hrbustoj 1429 二分+计算几何
http://www.bubuko.com/infodetail-1121744.html 在这个上面学习了方法 如果要判断巨量的点 就应该使用二分法 思路是先从a[1] a[n] a[2]来判断是否 ...
随机推荐
- Sql Server中启用分布式事务小结
1.web服务器与数据库服务器同时启动msdtc服务 2. 2台服务器做出如下配置: 控制面板->管理工具->组件服务->计算机->我的电脑->本地DTC .Net示例: ...
- 通过开源程序同时解决DNS劫持和DNS污染的问题
我们知道,某些网络运营商为了某些目的,对DNS进行了某些操作,导致使用ISP的正常上网设置无法通过域名取得正确的IP地址.常用的手段有:DNS劫持和DNS污染.关于DNS劫持和DNS污染的区别,请查找 ...
- [Angularjs]ng-switch用法
用法描述 ng-switch根据表达式的值显示或这隐藏对应部分.类似c#或者其他预览里面的switch用法.可以慢慢体会. 说道ng-switch就要说到子元素该怎么根据当前值进行变化.子元素可以通过 ...
- C语言代码优化(转)
.选择合适的算法和数据结构 选择一种合适的数据结构很重要,如果在一堆随机存放的数中使用了大量的插入和删除指令,那使用链表要快得多.数组与指针语句具有十分密切的关系,一般来说,指针比较灵活简洁,而数组则 ...
- HDOJ 1524 A Chess Game
A Chess Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- [Effective JavaScript 笔记]第34条:在原型中存储方法
js中完全有可能不借助原型进行编程.不用在其原型中定义任何的方法. 创建对象 构造函数法 所有属性和方法都在构造函数中定义 function User(name,pwd){ this.name=nam ...
- Win10如何隐藏Windows Defender任务栏图标
导读 Windows 10 至发布以来就内置集成了 Windows Defender 安全防护应用,但有许多用户平常压根儿就没注意到它的存在.微软为了使安全防护功能更加明显,Windows 10 周年 ...
- UItableView 编辑
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:( ...
- ZJOI Day 2 游记
---恢复内容开始--- 去ZJOI Day 2打了一会酱油...各种神犇大爷都来屠,南外的小朋友也来屠我们了真是感动...没有看到毛爷爷真是可惜.. Day[-1] 早上还在上课,吃完中饭立马跑去找 ...
- Balanced Teams (USACO Jan Bronze 2014)
既然是bronze,毫无压力的AC了. 就是个深搜,当然加个剪枝--最后一个组不用搜. 恩可以一个一个组分层次dfs,这样会跑得飞起~~也不容易错 #include <cstdio> in ...