要点

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

    488 绿豆蛙的归宿  时间限制: 1 s  空间限制: 64000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 随着新版百度空间的上线,Blog宠物绿豆 ...

  2. 构建嵌入式小型Linux系统

    构建嵌入式小型Linux系统 摘要:用buildroot构建x86的交叉编译工具链:裁减linux内核,尽可能做到最小:手工构建根文件系统:安装qemu虚拟机,仿真新配置的Linux系统:为新配置的L ...

  3. jexus入门

    参考:https://www.linuxdot.net/bbsfile-3084 一.Jexus简介:Jexus web server for linux 是一款基于.NET兼容环境,运行于Linux ...

  4. WPF中Xaml编译正常而Designer Time时出错的解决办法

    开发wpf时我们经常遇到一个xaml文件在设计时显示解析错误(比如在:VS或者Blend)而编译正常运行正常. 原因是:xaml的在Debug版本下必须为anyCPU. 解决办法: 1.打开工程文件x ...

  5. WCF中WcfSvcHost.exe如何禁止自动启动

    今天同事问在一个WCF server的解决方案里调试时如何禁止Server自动启动. 经过调查发现, VS的工具WcfSvcHost会在调试时自动扫描工程里的WCF server, 然后启动起来. 如 ...

  6. 采用MySQL_upgrade升级授权表方式升级

    1.7.1 采用MySQL_upgrade升级授权表方式升级(1) 这种升级方式比较省事,通过MySQL_upgrade命令即可完成.下面来演示一下整个升级过程. 1)修改my.cnf配置文件,因为M ...

  7. loadrunner手动生成脚本函数

    1.点击insert

  8. http请求中的get和post的区别

    1.标准答案 GET在浏览器回退时是无害的,而POST会再次提交请求. GET产生的URL地址可以被Bookmark,而POST不可以. GET请求会被浏览器主动cache,而POST不会,除非手动设 ...

  9. 对vuex的理解

    我用的vue安装了一个插件vuex插件 有3个 文件夹分别是actions(用于数据请求),getters(用于监听store),store(用于存储数据),

  10. Angular10 组件之间的通讯

    1 父组件和子组件之间的通讯 2 利用中间组件实现两个组件之间的通讯 3 利用服务实现两个组件之间的通讯 2017年8月26日20:09:13 待更新... 1 组件之间的关系图 1.1 父子关系 1 ...