要点

  • 红蓝点分别求凸包显然
  • 判断两凸包是否相交方法:所有红点不在蓝凸包内,反之亦然;所有红凸包线不与蓝凸包线相交,反之亦然。
  • 书上让特判一下凸包退化成点或线段的情况,为什么我感觉代码仓库的代码并没特判并且线段交和点在线段上写的是不包含端点的???
#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(凸包、线段交、点在多边形内)的更多相关文章

  1. UVA 10256 The Great Divide(点在多边形内)

    The Great Divid [题目链接]The Great Divid [题目类型]点在多边形内 &题解: 蓝书274, 感觉我的代码和刘汝佳的没啥区别,可是我的就是wa,所以贴一发刘汝佳 ...

  2. POJ 1584 A Round Peg in a Ground Hole 判断凸多边形 点到线段距离 点在多边形内

    首先判断是不是凸多边形 然后判断圆是否在凸多边形内 不知道给出的点是顺时针还是逆时针,所以用判断是否在多边形内的模板,不用是否在凸多边形内的模板 POJ 1584 A Round Peg in a G ...

  3. UVa 10256 凸包简单应用

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  4. UVa 10256 - The Great Divide 判断凸包相交

    模板敲错了于是WA了好几遍…… 判断由红点和蓝点分别组成的两个凸包是否相离,是输出Yes,否输出No. 训练指南上的分析: 1.任取红凸包上的一条线段和蓝凸包上的一条线段,判断二者是否相交.如果相交( ...

  5. 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 ...

  6. POJ 1410 Intersection(判断线段交和点在矩形内)

    Intersection Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9996   Accepted: 2632 Desc ...

  7. POJ - 1584 A Round Peg in a Ground Hole(判断凸多边形,点到线段距离,点在多边形内)

    http://poj.org/problem?id=1584 题意 按照顺时针或逆时针方向输入一个n边形的顶点坐标集,先判断这个n边形是否为凸包. 再给定一个圆形(圆心坐标和半径),判断这个圆是否完全 ...

  8. poj3335 半交平面,多边形内核

    Rotating Scoreboard Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5300   Accepted: 21 ...

  9. POJ 1556 The Doors(线段交+最短路)

    The Doors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5210   Accepted: 2124 Descrip ...

随机推荐

  1. Oracle中spool命令实现的两种方法比较

    ---恢复内容开始--- 要输出符合要求格式的数据文件只需在select时用字符连接来规范格式.比如有如下表 SQL>; select id,username,password from myu ...

  2. VBScript 内置函数

    本页列出了所有内建的 VBScript 函数: Date/Time 函数 Conversion 函数 Format 函数 Math 函数 Array 函数 String 函数 其他函数 Date/Ti ...

  3. Oracle 12C 新特性之级联truncate

    12c之前的版本中,在子表引用一个主表以及子表存在记录的情况下,是不提供截断此主表操作的.而在 12c 中的带有 CASCADE 操作的TRUNCATE TABLE 可以截断主表中的记录,并自动对子表 ...

  4. jquery 中post 、get的同步问题,从外部获取返回数据

    解决方法1: 在全局设置: $.ajaxSetup({ async : false }); $.ajaxSetup({ async : false }); 然后再使用post或get方法 $.get( ...

  5. 第 1 课 Go 简介

    (课程地址: http://study.163.com/course/courseLearn.htm?courseId=306002&from=study#/learn/video?lesso ...

  6. union联合体学习

    union,中文名“联合体.共用体”,在某种程度上类似结构体struct的一种数据结构,共用体(union)和结构体(struct)同样可以包含很多种数据类型和变量. 不过区别也挺明显: 结构体(st ...

  7. CentOS 7 破解mariadb密码

    1.停止mariadb服务: systemctl stop mariadb 2.进入单用户模式: mysqld_safe  --skip-grant-tables & 3.切换到另外一个工作组 ...

  8. how to download a file with Nodejs(without using third-party libraries)用node下载文件

    创建HTTP GET请求并将其管理response到可写文件流中: var http = require('http'); var fs = require('fs'); var file = fs. ...

  9. 项目一:第一天 1、项目概述 2、环境搭建(重点) 3、Jquery Easyui 前端UI框架 4、Jquery Ztree 树形插件使用

    1.项目环境 注:添加jar包直接在common_parent里面添加. 搭建数据库 create tablespace bos317space datafile 'c:\ bos317.dbf'   ...

  10. 16.CTF综合靶机渗透(九)

    Boot2root challenges aim to create a safe environment where you can perform real-world penetration t ...