UVa 10256(凸包、线段交、点在多边形内)
要点
- 红蓝点分别求凸包显然
- 判断两凸包是否相交方法:所有红点不在蓝凸包内,反之亦然;所有红凸包线不与蓝凸包线相交,反之亦然。
- 书上让特判一下凸包退化成点或线段的情况,为什么我感觉代码仓库的代码并没特判并且线段交和点在线段上写的是不包含端点的???
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
typedef double db;
const db PI = acos(-1);
const db eps = 1e-9;
const int maxn = 505;
int dcmp(db x) {
if (fabs(x) < eps) return 0;
return x > 0 ? 1 : -1;
}
struct Point {
db x, y;
Point(){}
Point(db a, db b):x(a), y(b){}
bool operator < (const Point &rhs) const {
if (dcmp(x - rhs.x) != 0) return dcmp(x - rhs.x) < 0;
return dcmp(y - rhs.y) < 0;
}
};
typedef Point Vector;
Vector operator + (Vector A, Vector B) { return Vector(A.x + B.x, A.y + B.y); }
Vector operator - (Vector A, Vector B) { return Vector(A.x - B.x, A.y - B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x * p, A.y * p); }
Vector operator / (Vector A, double p) { return Vector(A.x / p, A.y / p); }
bool operator == (const Vector& A, const Vector& B) { return dcmp(A.x - B.x) == 0 && dcmp(A.y - B.y) == 0; }
db Dot(Vector A, Vector B) { return A.x * B.x + A.y * B.y; }//点积
db Cross(Vector A, Vector B) { return A.x * B.y - A.y * B.x; }//叉积
bool isPointOnSegment(Point P, Point A, Point B) { return dcmp(Cross(A - P, B - P)) == 0 && dcmp(Dot(A - P, B - P)) <= 0; }//点在线段上(包含端点,把<=改为<即为不包含端点)
bool Segment_Proper_Intersection(Point a1, Point a2, Point b1, Point b2) {//线段a1a2与b1b2相交(包含端点)
db c1 = Cross(a2 - a1, b1 - a1), c2 = Cross(a2 - a1, b2 - a1);
db c3 = Cross(b2 - b1, a1 - b1), c4 = Cross(b2 - b1, a2 - b1);
if (isPointOnSegment(a1, b1, b2) || isPointOnSegment(a2, b1, b2))//某点在另一条线段上
return 1;
if (isPointOnSegment(b1, a1, a2) || isPointOnSegment(b2, a1, a2))
return 1;
return dcmp(c1)*dcmp(c2) < 0 && dcmp(c3)*dcmp(c4) < 0;
}
int isPointInPolygon(Point p, Vector *poly, int poly_size) {
if (poly_size == 1) return p == poly[0];//多边形退化成点的特判
int wn = 0;
int n = poly_size;
for (int i = 0; i < n; i++) {
if (isPointOnSegment(p, poly[i], poly[(i + 1) % n])) return -1;//在边界上
int k = dcmp(Cross(poly[(i + 1) % n] - poly[i], p - poly[i]));
int d1 = dcmp(poly[i].y - p.y);
int d2 = dcmp(poly[(i + 1) % n].y - p.y);
if (k > 0 && d1 <= 0 && d2 > 0) wn++;
if (k < 0 && d2 <= 0 && d1 > 0) wn--;
}
if (wn != 0) return 1;//内部
return 0;//外部
}
void ConvexHull(Point *p, int n, Point *v, int &cnt) {
cnt = 0;
sort(p, p + n);
n = unique(p, p + n) - p;//去重
for (int i = 0; i < n; i++) {
while (cnt > 1 && dcmp(Cross(v[cnt - 1] - v[cnt - 2], p[i] - v[cnt - 2])) <= 0) cnt--;
v[cnt++] = p[i];
}
int k = cnt;
for (int i = n - 2; ~i; --i) {
while (cnt > k && dcmp(Cross(v[cnt - 1] - v[cnt - 2], p[i] - v[cnt - 2])) <= 0) cnt--;
v[cnt++] = p[i];
}
if (n > 1) cnt--;
}
int n, m, Acnt, Bcnt;
Point A[maxn], B[maxn], Av[maxn], Bv[maxn];
int main() {
while (~scanf("%d %d", &n, &m) && (n | m)) {
for (int i = 0; i < n; i++)
scanf("%lf %lf", &A[i].x, &A[i].y);
for (int i = 0; i < m; i++)
scanf("%lf %lf", &B[i].x, &B[i].y);
ConvexHull(A, n, Av, Acnt);
ConvexHull(B, m, Bv, Bcnt);
bool flag = 0;
for (int i = 0; i < n; i++)
if (isPointInPolygon(A[i], Bv, Bcnt) != 0) {
flag = 1; break;
}
for (int i = 0; i < m; i++)
if (isPointInPolygon(B[i], Av, Acnt) != 0) {
flag = 1; break;
}
if (flag) goto here;
for (int i = 0; i < Acnt; i++) {
Point a1 = Av[i], a2 = Av[(i + 1) % Acnt];
for (int j = 0; j < Bcnt; j++) {
Point b1 = Bv[j], b2 = Bv[(j + 1) % Bcnt];
if (Segment_Proper_Intersection(a1, a2, b1, b2)) {
flag = 1; break;
}
}
if (flag) break;
}
here:
printf("%s\n", flag ? "No" : "Yes");
}
}
UVa 10256(凸包、线段交、点在多边形内)的更多相关文章
- UVA 10256 The Great Divide(点在多边形内)
The Great Divid [题目链接]The Great Divid [题目类型]点在多边形内 &题解: 蓝书274, 感觉我的代码和刘汝佳的没啥区别,可是我的就是wa,所以贴一发刘汝佳 ...
- POJ 1584 A Round Peg in a Ground Hole 判断凸多边形 点到线段距离 点在多边形内
首先判断是不是凸多边形 然后判断圆是否在凸多边形内 不知道给出的点是顺时针还是逆时针,所以用判断是否在多边形内的模板,不用是否在凸多边形内的模板 POJ 1584 A Round Peg in a G ...
- UVa 10256 凸包简单应用
题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- UVa 10256 - The Great Divide 判断凸包相交
模板敲错了于是WA了好几遍…… 判断由红点和蓝点分别组成的两个凸包是否相离,是输出Yes,否输出No. 训练指南上的分析: 1.任取红凸包上的一条线段和蓝凸包上的一条线段,判断二者是否相交.如果相交( ...
- POJ 1584 A Round Peg in a Ground Hole(判断凸多边形,点到线段距离,点在多边形内)
A Round Peg in a Ground Hole Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 4438 Acc ...
- POJ 1410 Intersection(判断线段交和点在矩形内)
Intersection Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 9996 Accepted: 2632 Desc ...
- POJ - 1584 A Round Peg in a Ground Hole(判断凸多边形,点到线段距离,点在多边形内)
http://poj.org/problem?id=1584 题意 按照顺时针或逆时针方向输入一个n边形的顶点坐标集,先判断这个n边形是否为凸包. 再给定一个圆形(圆心坐标和半径),判断这个圆是否完全 ...
- poj3335 半交平面,多边形内核
Rotating Scoreboard Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5300 Accepted: 21 ...
- POJ 1556 The Doors(线段交+最短路)
The Doors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5210 Accepted: 2124 Descrip ...
随机推荐
- C易位构词(华师网络赛)(错排)
Time limit per test: 2.0 seconds Memory limit: 256 megabytes 易位构词 (anagram),指将一个单词中的字母重新排列,原单词中的每个字母 ...
- POJ3621Sightseeing Cows
Sightseeing Cows Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10595 Accepted: 3632 ...
- 【C&C++】查看代码运行时间
查看代码运行时间有助于更好地优化项目代码 1. Windows平台 windows平台下有两种方式,精度有所不同,都需要包含<windows.h>头文件 1) DWORD GetTickC ...
- NSArray用法
//类方法初始化一个数组对象 [array count] : 得到这个数组对象的长度. [array objectAtIndex index]: 传入数组的索引(index) 得到数据对象. [arr ...
- java"=="与equals()方法的对照
总结:String s=new String(); s是在堆内存里的 String s2=new String(); s2是在堆内存又重新生成的一个. package com.da; //逆向思维:i ...
- JavaScript-Tool:template
ylbtech-JavaScript-Tool: 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 作者:ylbtech出处:http:/ ...
- Myeclipse如何使用Maven添加jar包
很多新手都不知道如何在maven项目里添加jar包. 以前我还没接触maven的时候下载过一个demo,是maven项目. 我居然是照着他的pom.xml文件一个一个的写!!! 很多人认为理所当然的东 ...
- ES6学习之Async函数
定义:Async函数是一个异步操作函数,本质上,Async函数是Generator函数的语法糖.async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await ...
- GEO(Gene Expression Omnibus):高通量基因表达数据库
Gene Expression Omnibus(GEO)是一个公共存储库,可以存档和自由分发由科学界提交的全套微阵列,新一代测序和其他形式的高通量功能基因组数据. 除数据存储外,还提供一系列基于Web ...
- 6.JBoss5.x6.x 反序列化漏洞(CVE-2017-12149)复现
2017 年 9 月 14 日,国家信息安全漏洞共享平台( CNVD )收录了 JBOSS Application Server 反序列化命令执行漏洞( CNVD-2017-33724,对应 CVE- ...