凸多边形

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. CentOS 6.6编译安装Nginx1.6.2+MySQL5.6.21+PHP5.6.3(转)

    vi /etc/sysconfig/iptables #编辑防火墙配置文件 # Firewall configuration written by system-config-firewall # M ...

  2. myBatis 实现用户表增删查改操作<方法1 没有使用接口的>(最终版)

    在UserMapper.xml中添加增删改查 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYP ...

  3. git配置global信息

    git 执行提交时,提示用户输入用户和邮箱 git commit -m '*add newCat file' newCat/ *** Please tell me who you are. Run g ...

  4. 记录一次centos6.4版本的VSFTP本地用户登陆的配置

    其实vsftp是一个非常常用而且简单的服务,但是假如服务不是你配置的前者没有留下参考档案,的确是件头疼的事儿,特此记录下. 首先是vsftp的安装当然安装有源码的编译和yum等 这里我选择rpm包的y ...

  5. 字符串模拟赛T2

    // source code from laekov for c0x17 #define PRID "fkqh" #include <cstdio> #include ...

  6. Bootstrap幻灯轮播如何支持触屏左右滑动手势?

    最近ytkah在学习用bootstrap搭建网站,Bootstrap能自适应pc端和手机端,并且移动设备优先,适合现如今移动营销.bootstrap是封装好的框架,需要某些功能只需调用相应的组件就可以 ...

  7. [Effective JavaScript 笔记]第56条:避免不必要的状态

    API有时被归为两类:有状态的和无状态的.无状态的API提供的函数或方法的行为只取决于输入,而与程序的状态改变无关.字符串的方法是无状态的.字符串的内容不能被修改,方法只取决于字符串的内容及传递给方法 ...

  8. 代码规范和常用的js插件以及测试工具

    1.代码规范 .model层 1.1.1database file_proerty 1.1.2java fileProperty. 1.2.字段要有空指针 1.3.不创建爱数据库外键约束 1.4.已知 ...

  9. Rotate bitmap by real angle

    tl;dr; Use GDI+ SetWorldTransform With WinAPI's SetWorldTransform you can transform the space of dev ...

  10. Linux_DHCP服务搭建

    Linux网络参数的设置 1.        修改主机名 # vim /etc/sysconfig/network NETWORKING=yes HOSTNAME=bj.com 2.        修 ...