凸多边形

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. linux环境下安装sphinx中文支持分词搜索(coreseek+mmseg)

     linux环境下安装sphinx中文支持分词搜索(coreseek+mmseg) 2013-11-10 16:51:14 分类: 系统运维 为什么要写这篇文章? 答:通过常规的三大步(./confi ...

  2. frameset用法

    <html> <frameset rows="15%,*" border="1" frameborder="1" scro ...

  3. C++中debug和release的区别 . 转载

    vc中debug和release的不同 收藏  在使用VC开发软件的过程中,正当要享受那种兴奋的时候突然发现:release与debug运行结果不一致,甚至出错,而release又不方便调试,真的是当 ...

  4. zabbix 分布式监控(proxy)源码安装

    安装分布式监控(代理节点) 1.下载软件zabbix-3.2.1.tar.gz 1.1 解压 wget http://nchc.dl.sourceforge.net/project/zabbix/ZA ...

  5. 宿主机为linux、windows分别实现VMware三种方式上网(转)

    一.VMware三种方式工作原理1 Host-only连接方式  让虚机具有与宿主机不同的各自独立IP地址,但与宿主机位于不同网段,同时为宿主主机新增一个IP地址,且保证该IP地址与各虚机IP地址位于 ...

  6. 关于FlexPaper 2.1.2版本 二次开发 Logo 、打印、搜索、缩略图、添加按钮、js交互、右键菜单、书签等相关问题

    2015-03-02 更新文章,由于需求修改,更改了flexpaper插件,故增加第9.10.11小节,下载代码时请注意. 先废话几句.最近用到文档在线浏览功能,之前用的是print2flash(一个 ...

  7. Unity3D如何制作透贴和使用透贴模型

    http://momowing.diandian.com/post/2012-10-25/40040842845 Unity3D如何制作透贴和使用透贴模型??解决办法!!! 问题: 同事通过3DMAX ...

  8. 杭电hdoj题目分类

    HDOJ 题目分类 //分类不是绝对的 //"*" 表示好题,需要多次回味 //"?"表示结论是正确的,但还停留在模块阶 段,需要理解,证明. //简单题看到就 ...

  9. 什么是响应式Web设计?怎样进行?

    http://beforweb.com/node/6/page/0/3 开始第一篇.老规矩,先无聊的谈论天气一类的话题.十一长假,天气也终于开始有些秋天的味道,坐在屋里甚至觉得需要热咖啡.话说两年前也 ...

  10. Android 下载文件及写入SD卡

    Android 下载文件及写入SD卡,实例代码 <?xml version="1.0" encoding="utf-8"?> <LinearL ...