先从给出的两个点集中分别计算出两个凸包,

然后推断两个凸包是否相离。

#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std; const double eps = 1e-10;
double dcmp(double x) {
if(fabs(x) < eps) return 0;
else return x < 0 ? -1 : 1;
} struct Point {
double x, y;
Point(double x=0, double y=0):x(x),y(y) {}
}; typedef Point Vector; Vector operator - (const Point& A, const Point& B) {
return Vector(A.x-B.x, A.y-B.y);
} double Cross(const Vector& A, const Vector& B) {
return A.x*B.y - A.y*B.x;
} double Dot(const Vector& A, const Vector& B) {
return A.x*B.x + A.y*B.y;
} bool operator < (const Point& p1, const Point& p2) {
return p1.x < p2.x || (p1.x == p2.x && p1.y < p2.y);
} bool operator == (const Point& p1, const Point& p2) {
return p1.x == p2.x && p1.y == p2.y;
} bool SegmentProperIntersection(const Point& a1, const Point& a2, const Point& b1, const Point& b2) {
double c1 = Cross(a2-a1,b1-a1), c2 = Cross(a2-a1,b2-a1),
c3 = Cross(b2-b1,a1-b1), c4=Cross(b2-b1,a2-b1);
return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
} bool OnSegment(const Point& p, const Point& a1, const Point& a2) {
return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0;
} // 点集凸包
// 假设不希望在凸包的边上有输入点,把两个 <= 改成 <
// 假设不介意点集被改动,能够改成传递引用
vector<Point> ConvexHull(vector<Point> p) {
// 预处理,删除反复点
sort(p.begin(), p.end());
p.erase(unique(p.begin(), p.end()), p.end()); int n = p.size();
int m = 0;
vector<Point> ch(n+1);
for(int i = 0; i < n; i++) {
while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
ch[m++] = p[i];
}
int k = m;
for(int i = n-2; i >= 0; i--) {
while(m > k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
ch[m++] = p[i];
}
if(n > 1) m--;
ch.resize(m);
return ch;
} int IsPointInPolygon(const Point& p, const vector<Point>& poly) {
int wn = 0;
int n = poly.size();
for(int i=0; i<n; ++i) {
const Point& p1 = poly[i];
const Point& p2 = poly[(i+1)%n];
if(p1 == p || p2 == p || OnSegment(p, p1, p2)) return -1;//在边界上
int k = dcmp(Cross(p2-p1, p-p1));
int d1 = dcmp(p1.y - p.y);
int d2 = dcmp(p2.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;
} bool ConvexPolygonDisjoint(const vector<Point> ch1, const vector<Point> ch2) {
int c1 = ch1.size();
int c2 = ch2.size();
for(int i=0; i<c1; ++i)
if(IsPointInPolygon(ch1[i], ch2) != 0) return false;
for(int i=0; i<c2; ++i)
if(IsPointInPolygon(ch2[i], ch1) != 0) return false;
for(int i=0; i<c1; ++i)
for(int j=0; j<c2; ++j)
if(SegmentProperIntersection(ch1[i], ch1[(i+1)%c1], ch2[j], ch2[(j+1)%c2])) return false;
return true;
} int main() {
int n, m;
while(scanf("%d%d", &n, &m) == 2 && n > 0 && m > 0) {
vector<Point> P1, P2;
double x, y;
for(int i = 0; i < n; i++) {
scanf("%lf%lf", &x, &y);
P1.push_back(Point(x, y));
}
for(int i = 0; i < m; i++) {
scanf("%lf%lf", &x, &y);
P2.push_back(Point(x, y));
}
if(ConvexPolygonDisjoint(ConvexHull(P1), ConvexHull(P2)))
printf("Yes\n");
else
printf("No\n");
}
return 0;
}

UVa 10256 The Great Divide,推断两个凸包是否相离的更多相关文章

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

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

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

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

  3. uva 10256 The Great Divide

    题意:给定两个点集,一个红点集,另一个蓝点集,询问,能否找到一条直线能,使得任取一个红点和蓝点都在直线异侧. 思路:划分成两个凸包,一个红包,一个蓝包.两个凸包不相交不重合. 1.任取一个凸包中的点不 ...

  4. UVA 10256 The Great Divide(凸包划分)

    The Great Divide Input: standard input Output: standard output Time Limit: 8 seconds Memory Limit: 3 ...

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

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

  6. UVa 10256 (判断两个凸包相离) The Great Divide

    题意: 给出n个红点,m个蓝点.问是否存在一条直线使得红点和蓝点分别分布在直线的两侧,这些点不能再直线上. 分析: 求出两种点的凸包,如果两个凸包相离的话,则存在这样一条直线. 判断凸包相离需要判断这 ...

  7. 【暑假】[数学]UVa 10375 Choose and divide

    UVa 10375 Choose and divide 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19601 思路 ...

  8. UVA - 10375 Choose and divide[唯一分解定理]

    UVA - 10375 Choose and divide Choose and divide Time Limit: 1000MS   Memory Limit: 65536K Total Subm ...

  9. 005推断两个字符串是否是变位词 (keep it up)

    写一个函数推断两个字符串是否是变位词. 变位词(anagrams)指的是组成两个单词的字符同样,但位置不同的单词.比方说, abbcd和abcdb就是一对变位词 这也是简单的题. 我们能够排序然后对照 ...

随机推荐

  1. oracle之substr函数

    substr(字符串,截取开始位置,截取长度) //返回截取的字 substr(,) //返回结果为 'H' *从字符串第一个字符开始截取长度为1的字符串 substr(,) //返回结果为 'H' ...

  2. python - 面向对象(二)

    类的三大特性 类的三大特性包括: 封装.继承.多态 一.封装 封装就是将类所用到的所有字段.属性.方法都包含在类代码段里面,当实例调用直接调用类中的方法即可. class People(object) ...

  3. ASP.Net MVC概念及基本

    1.1概念 MVC是一种软件设计模式,即:Model(模型).View(视图).Controller(控制器)  .其主要设计目标是将用户接口和逻辑层相分离,以便开发人员更好的关注逻辑层的设计和测试, ...

  4. ASP.NET 动态编译、预编译和 WebDeployment 项目(转)

    概述 在 Web 服务器上,既可以部署源文件,也可以部署编译后程序集. 若部署源文件,则当用户访问时,Web 应用程序会被动态编译,并缓存该程序集,以便下次访问. 否则,若部署程序集,Web 应用程序 ...

  5. hdu1087 简单DP

    I - 简单dp 例题扩展 Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:32768KB     ...

  6. rman全库恢复到不同主机,不同实例名,不同目录下

    一.配置目标主机的ip.hostname及与源端主机的连通性 1.配置目标主机IP 使用图形界面配置IP: administration----network---修改IP(指定静态IP) deact ...

  7. HTML5 video 事件

    1.获取视频时间长度 当视频载入video后,使用 onloadedmetadata 事件获取视频的时间长度. video.onloadedmetadata = function () { var v ...

  8. linux 文件查找和压缩工具

    文件查找 1,which命行查找可执行文件,which 只会搜索系统$PATH目录 2,whereis,查找可执行文件,并显示出此文件的man page文件,并且可以查找到系统的库目录 3,locat ...

  9. 机器学习之K近邻算法(KNN)

    机器学习之K近邻算法(KNN) 标签: python 算法 KNN 机械学习 苛求真理的欲望让我想要了解算法的本质,于是我开始了机械学习的算法之旅 from numpy import * import ...

  10. Lonely Integer

    https://www.hackerrank.com/challenges/lonely-integer def main(): n = int(raw_input()) s = dict() a = ...