ZOJ 1081 Points Within | 判断点在多边形内
题目:
给个n个点的多边形,n个点按顺序给出,给个点m,判断m在不在多边形内部
题解:
网上有两种方法,这里写一种:射线法
大体的思想是:以这个点为端点,做一条平行与x轴的射线(代码中射线指向x轴正方向)
如果交点个数为奇数的话就在内部,如果为偶数(包括0)就在外部

#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 105
using namespace std;
int n,m;
struct point//点(向量的结构体)
{
int x,y;
point() {}//初始化
point (int _x,int _y) :
x(_x),y(_y) {};//用一对坐标初始化点
inline point operator + (const point &rhs) const//向量加法
{
return point(x+rhs.x,y+rhs.y);
}
inline point operator - (const point &rhs) const//向量减法
{
return point(x-rhs.x,y-rhs.y);
}
inline int operator * (const point &rhs) const//向量叉乘
//向量叉乘的几何意义是以两个向量为邻边的平行四边形的有向面积 也就是|a|*|b|*sin<a,b> 这里的sin<a,b>决定了
//如果a,b是逆时针的,那么sin<a,b>大于0,有向面积大于0,反之<0
{
return x*rhs.y-y*rhs.x;
}
friend inline int dot(const point &lhs,const point &rhs)//向量点乘
{
return lhs.x*rhs.x+lhs.y*rhs.y;
}
}q;
inline int check(const point &u,const point &v,const point &p)//判断点是不是在线段上
//u,v是线段端点,p是点
{
int det=(u-p)*(v-p);//如果向量(u-p)*(v-p)==0就说明u,v,p共线(因为没面积)
if (det!=0) return 0;
int Dot=dot(u-p,v-p);//如果(u-p)点乘(v-p)<=0 就说明点在线段上
return Dot<=0;
}
struct polygon//多边形结构体
{
int n;
point p[N];
void init(int _n)
{
n=_n;
for (int i=0;i<n;i++)
scanf("%d%d",&p[i].x,&p[i].y);
p[n]=p[0];
if (Area()<0) reverse(p,p+n);//通过判断多边形的有向面积来把点规范成逆时针的
p[n]=p[0];
}
inline int Area() const
//计算多边形的有向面积(如果点是逆时针的话就是正的,否则是负的)
{
int ret=0;
for (int i=0;i<n;i++)
ret+=p[i]*p[i+1];
return ret=0;
}
bool inner (const point &q)//判断点是不是在多边形内部
{
int cnt=0;
for (int i=0;i<n;i++)
{
if (check(p[i],p[i+1],q)) return 1;//如果点在线段上显然可以
int d1=p[i].y-q.y,d2=p[i+1].y-q.y;
int det=(p[i]-q)*(p[i+1]-q);
if ( (det>=0 && d1<0 && d2>=0) ||
(det<=0 && d1>=0 && d2<0)) ++cnt;//第一个条件是判断p在多边形内的时候,第二个是判断p在多边形外的时候
}
return cnt&1;
}
}P; int main()
{
for (int tt=1;;tt++)
{
scanf("%d",&n);
if (n==0) break;
scanf("%d",&m);
P.init(n);
if (tt!=1)
putchar('\n');
printf("Problem %d:\n",tt);
while (m--)
{
scanf("%d%d",&q.x,&q.y);
if (P.inner(q)) puts("Within");
else puts("Outside");
}
}
return 0;
}
ZOJ 1081 Points Within | 判断点在多边形内的更多相关文章
- [zoj] 1081 Points Within || 判断点是否在多边形内
原题 多组数据. n为多边形顶点数,m为要判断的点数 按逆时针序给出多边形的点,判断点是否在多边形内,在的话输出"Within",否则输出"Outside" / ...
- ZOJ 1081 Within(点是否在多边形内)| 计算几何
ZOJ 1081 Within 我使用的是"射线法":从该点出发,作一条向左的水平射线,与多边形的边的交点有奇数个则点在多边形内. 需要注意的点: 如果点在多边形的边上特判. 考虑 ...
- zoj 1081 判断点在多边形内
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=81Points Within Time Limit: 2 Second ...
- R树判断点在多边形内-Java版本
1.什么是RTree 待补充 2.RTree java依赖 rtree的java开源版本在GitHub上:https://github.com/davidmoten/rtree 上面有详细的使用说明 ...
- 判断点在多边形内算法的C++实现
目录 1. 算法思路 2. 具体实现 3. 改进空间 1. 算法思路 判断平面内点是否在多边形内有多种算法,其中射线法是其中比较好理解的一种,而且能够支持凹多边形的情况.该算法的思路很简单,就是从目标 ...
- hdu 1756:Cupid's Arrow(计算几何,判断点在多边形内)
Cupid's Arrow Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- php之判断点在多边形内的api
1.判断点在多边形内的数学思想:以那个点为顶点,作任意单向射线,如果它与多边形交点个数为奇数个,那么那个点在多边形内,相关公式: <?php class AreaApi{ //$area是一个多 ...
- POJ 2318 TOYS | 二分+判断点在多边形内
题意: 给一个矩形的区域(左上角为(x1,y1) 右下角为(x2,y2)),给出n对(u,v)表示(u,y1) 和 (v,y2)构成线段将矩形切割 这样构成了n+1个多边形,再给出m个点,问每个多边形 ...
- zoj 1081:Points Within(计算几何,判断点是否在多边形内,经典题)
Points Within Time Limit: 2 Seconds Memory Limit: 65536 KB Statement of the Problem Several dra ...
随机推荐
- AMD、CMD、Common规范及对比
https://blog.csdn.net/bluesky1215/article/details/71081780 1.名词解释 AMD:Asynchronous Modules Definiti ...
- 泉五培训Day4
T1 收果子 题目 [题目描述] 有一个果园,有n棵果树依次排成一排,其中已知第 i 棵果树上结了ai个果子.现在要按照果树编号顺序依次收果子,对于一个能装v个果树的果篮,收果子从第1棵果树开始,如果 ...
- 懒下载软件,一行代码连接wifi^_^
按键盘的windows+R,输入cmd,回车键 设置语句netsh wlan set hostednetwork mode=allow ssid=user key=possword 按回车键 启动语句 ...
- Servlet学习笔记04——什么是重定向,servlet生命周期?
1.重定向 (1)什么是重定向? 服务器通知浏览器访问一个新的地址. 注: 服务器可以通过发送一个302状态码及一个 Location消息头(该消息头的值是一个地址,一般 称之为重定向地址)给浏览器, ...
- 执行pip命令时遇到 Fatal error in launcher: Unable to create process using '"'
电脑同时安装了python-2.7.13跟python-3.6.1,安装时勾选了pip,环境变量也已经配置好. 为了方便运行,同时修改了可执行文件为 python2和python3.此时在cmd命令行 ...
- python文件,字符串,二进制的读写
读文件: f = open('/Users/michael/test.txt', 'r') #一次读取文件的全部内容 f.read() #文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且 ...
- 代理缓存服务之Squid
代理缓存服务 Squid是linux系统中最为流行的一款高性能代理服务软件,通常用作Web网站的前置缓存服务,能够代替用户向网站服务器请求页面数据并进行缓存. 简单来说,Squid服务程序会按照收到的 ...
- 20145202 《Java程序设计》实验四实验报告
实验名称 Andoid开发基础 实验内容 1.基于Android Studio开发简单的Android应用并部署测试; 2.了解Android组件.布局管理器的使用: 3.掌握Android中事件处理 ...
- 腾讯云分析MTA HTML5接入方法
从微信服务号或订阅号里跳转到自己项目后,想在项目中统计出实时数据.历史趋势.实时访客.新老访客比.访客画像.地域信息.运营商.终端信息.页面排行.性能监控.访问深度.外部链接.入口页面.离开页面.渠道 ...
- 《Cracking the Coding Interview》——第2章:链表——题目4
2014-03-18 02:27 题目:将一个单链表按照一个值X分为两部分,小于X的部分放在大于等于X的部分之前. 解法:按照值和X的大小,分链表为两条链表,然后连起来成一条. 代码: // 2.4 ...