题目链接:http://lightoj.com/volume_showproblem.php?problem=1190

题意:给你一个多边形含有n个点;然后又m个查询,每次判断点(x, y)是否在多边形的内部;

射线法判断即可适用于任何(凸或凹)多边形;时间复杂度为O(n);

判断一个点是在多边形内部,边上还是在外部,时间复杂度为O(n);射线法可以正确用于凹多边形;

射线法是使用最广泛的算法,这是由于相比较其他算法而言,它不但可以正确使用在凹多边形上,而且不需要考虑精度误差问题。该算法思想是从点出发向右水平做

一条射线,计算该射线与多边形的边的相交点个数,当点不在多边形边上时,如果是奇数,那么点就一定在多边形内部,否则,在外部。

/*
射线法:判断一个点是在多边形内部,边上还是在外部,时间复杂度为O(n);
射线法可以正确用于凹多边形;
射线法是使用最广泛的算法,这是由于相比较其他算法而言,它不但可以正
确使用在凹多边形上,而且不需要考虑精度误差问题。该算法思想是从点出
发向右水平做一条射线,计算该射线与多边形的边的相交点个数,当点不在
多边形边上时,如果是奇数,那么点就一定在多边形内部,否则,在外部。
*/
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int N = ;
const double eps = 1e-;
const int INF = 0x3f3f3f3f;
//////////////////////////////////////////////////////////////////
struct point
{
double x, y;
point(double x=, double y=) : x(x), y(y){}
friend point operator - (const point& p1, const point& p2)
{
return point(p1.x-p2.x, p1.y-p2.y);
}
friend double operator ^ (const point& p1, const point& p2)
{
return p1.x*p2.y - p1.y*p2.x;
}
};
//////////////////////////////////////////////////////////////////
struct Segment
{
point s, e;
};
//////////////////////////////////////////////////////////////////
///判断一个double类型的数是 0 <0 >0;
int Sign(double x)
{
if( fabs(x) < eps )return ;
if(x > )return ;
return -;
}
//////////////////////////////////////////////////////////////////
///判断o在ab的哪边;0:o在直线ab上; >0:在左边; <0:在右边;
double cross(point o, point a, point b)
{
return ((a-o)^(b-o));
}
//////////////////////////////////////////////////////////////////
///已知abc三点在一条直线上,判断点a是否在线段bc之间;<=0:在 >0:不在;
int Between(point a, point b, point c)
{
if(fabs(b.x-c.x) > fabs(b.y-c.y))
return Sign(min(b.x, c.x)-a.x)*Sign(max(b.x, c.x)-a.x);
else
return Sign(min(b.y, c.y)-a.y)*Sign(max(b.y, c.y)-a.y);
}
//////////////////////////////////////////////////////////////////
///判断点p0和线段S上,<=0:在,1:不在;
int PointOnSegment(point p0, Segment S)
{
if(Sign(cross(S.s, S.e, p0)) == )
return Between(p0, S.s, S.e);
return ;
}
//////////////////////////////////////////////////////////////////
///求线段a和线段b的交点个数;
int SegmentCross(Segment a, Segment b)
{
double x1 = cross(a.s, a.e, b.s);
double x2 = cross(a.s, a.e, b.e);
double x3 = cross(b.s, b.e, a.s);
double x4 = cross(b.s, b.e, a.e); if(Sign(x1*x2)< && Sign(x3*x4)<) return ;
if((Sign(x1)== && Between(b.s, a.s, a.e)<=) ||
(Sign(x2)== && Between(b.e, a.s, a.e)<=) ||
(Sign(x3)== && Between(a.s, b.s, b.e)<=) ||
(Sign(x4)== && Between(a.e, b.s, b.e)<=))
return ;
return ;
}
//////////////////////////////////////////////////////////////////
///判断点p0与含有n个节点的多边形的位置关系,p数组是顶点集合;
///返回0:边上或顶点上, 1:外面, -1:里面;
int PointInPolygon(point p0, point p[], int n)
{
Segment L, S;
point temp;
L.s = p0, L.e = point(INF, p0.y);///以p0为起点的射线L; int counts = ;
p[n] = p[]; for(int i=; i<=n; i++)
{
S.s = p[i-], S.e = p[i]; if(PointOnSegment(p0, S) <= ) return ;
if(S.s.y == S.e.y) continue;///和射线平行; if(S.s.y > S.e.y) temp = S.s;
else temp = S.e; if(PointOnSegment(temp, L) == -)
counts ++;
else if(SegmentCross(L, S) == )
counts ++;
}
if(counts%) return -;
return ;
}
//////////////////////////////////////////////////////////////////
int main()
{
point p[N];
int T, tCase = , n, q;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(int i=; i<n; i++)
scanf("%lf %lf", &p[i].x, &p[i].y);
scanf("%d", &q);
printf("Case %d:\n", tCase++);
for(int i=; i<=q; i++)
{
int x, y;
scanf("%d %d", &x, &y);
int ans = PointInPolygon(point(x, y), p, n);
if(ans == ) puts("No");
else puts("Yes");
}
}
return ;
}

LightOj1190 - Sleepwalking(判断点与多边形的位置关系--射线法模板)的更多相关文章

  1. Cupid's Arrow---hdu1756(判断点与多边形的位置关系 模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1756 题意:中文题,套模板即可: /* 射线法:判断一个点是在多边形内部,边上还是在外部,时间复杂度为 ...

  2. luogu 1355 神秘大三角 判断点和三角形的位置关系 面积法 叉积法

    题目链接 题目描述 判断一个点与已知三角形的位置关系. 输入输出格式 输入格式: 前三行:每行一个坐标,表示该三角形的三个顶点 第四行:一个点的坐标,试判断该点与前三个点围成三角形的位置关系 (详见样 ...

  3. 叉积_判断点与三角形的位置关系 P1355 神秘大三角

    题目描述 判断一个点与已知三角形的位置关系. 输入输出格式 输入格式: 前三行:每行一个坐标,表示该三角形的三个顶点 第四行:一个点的坐标,试判断该点与前三个点围成三角形的位置关系 (详见样例) 所有 ...

  4. ZOJ1081 Points Within 点和多边形的位置关系

    ZOJ1081 给一个点和一个多边形 判断点在多边形内(边上)还是在多边形外 在多边形外的点引一条射线必然穿过多边形的两条边 而在多边形内的点则不一定. 当然凹多边形有特殊情况 但是总能找到对应位置关 ...

  5. 判断两条直线的位置关系 POJ 1269 Intersecting Lines

    两条直线可能有三种关系:1.共线     2.平行(不包括共线)    3.相交. 那给定两条直线怎么判断他们的位置关系呢.还是用到向量的叉积 例题:POJ 1269 题意:这道题是给定四个点p1, ...

  6. POJ_2318_TOYS&&POJ_2398_Toy Storage_二分+判断直线和点的位置关系

    POJ_2318_TOYS&&POJ_2398_Toy Storage_二分+判断直线和点的位置 Description Calculate the number of toys th ...

  7. POJ 2318 /// 判断点与直线的位置关系

    题目大意: n块玩具箱隔板 m个玩具落地点 给定玩具箱的左上和右下两个端点 接下来给定n块隔板的上点的x和下点的x(因为y就是玩具箱的上下边缘) 接下来给定m个玩具落地点 输出n+1个区域各有的玩具数 ...

  8. Segments---poj3304(判断直线与线段的位置关系)

    题目链接:http://poj.org/problem?id=3304 题意:给你n个线段,求是否有一条直线与所有的线段都相交,有Yes,没有No; 枚举所有的顶点作为直线的两点,然后判断这条直线是否 ...

  9. UVA 10256 The Great Divide (凸包,多边形的位置关系)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34148 [思路] 凸包 求出红蓝点的凸包,剩下的问题就是判断两个凸 ...

随机推荐

  1. BZOJ4155 : [Ipsc2015]Humble Captains

    第一问最小割,第二问: 设du[i]表示i点的度数,则要最小化$\frac{|1集合的du[i]之和-2集合的du[i]之和|}{2}$, 压位01背包即可. #include<cstdio&g ...

  2. BZOJ3448 : [Usaco2014 Feb]Auto-complete

    RE了几十发,实在没办法了…只好向管理员要数据,然后发现数据规模与题目描述不符… 建立Trie并求出DFS序,同时根据DFS序确定字典序 然后每次询问相当于询问子树第k小,用主席树维护,注意压缩内存 ...

  3. 关于 Apple Metal API 的一些想法

    在看完 Metal 的开发文档后,除了官方所宣称的一些优点外(比如说更容易理解和使用的 API,更直接和精细的硬件控制,减少 GPU 使用过程中的 CPU 额外开销等等),从我有限的 GLES 开发经 ...

  4. Google Code Jam 2009 Qualification Round Problem C. Welcome to Code Jam

    本题的 Large dataset 本人尚未解决. https://code.google.com/codejam/contest/90101/dashboard#s=p2 Problem So yo ...

  5. 外部调用JS文件时出现中文乱码的解决办法

    若测试网页的编码格式为:gb2312,而调用外部JS文件时出现了乱码(前提是JS文件无错误),则将调用的外部JS文件用记事本打开,然后再保存成编码格式为UTF-8的JS文件即可. 若测试网页的编码格式 ...

  6. 关于UIWebView的总结

    关于UIWebView的总结 前言 今天参加了 Adobe 和 CSDN 组织的一个关于 PhoneGap 的开发讲座 ,而 PhoneGap 在 iOS 设备上的实现就是通过 UIWebView 控 ...

  7. SQL - 分页存储过程

    http://www.jb51.net/article/71193.htm http://www.webdiyer.com/utils/spgenerator/ create PROCEDURE [d ...

  8. Linux /etc/passwd 和 /etc/group 文件格式

    passwd: /etc/passwd 文件结构 2011-04-29 16:32:54| 分类: ubuntu技巧 | 标签:passwd linux ubuntu fadero centos./e ...

  9. IOS第四天(4:下一题和选框的实现)

    #import "HMViewController.h" #import "HMQuestion.h" #define kButtonWidth 35 #def ...

  10. 【新产品发布】【iCore2 ARM / FPGA 双核心板】

    iCore2是一款包含ARM / FPGA两大利器的双核心板.ARM方面,采用意法半导体高性能的32位Cortex-M3内核STM32F103VE微处理器,主频达72MHz,并包含丰富外设接口.FPG ...