UVa 10256 The Great Divide,推断两个凸包是否相离
先从给出的两个点集中分别计算出两个凸包,
然后推断两个凸包是否相离。
#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,推断两个凸包是否相离的更多相关文章
- UVa 10256 - The Great Divide 判断凸包相交
模板敲错了于是WA了好几遍…… 判断由红点和蓝点分别组成的两个凸包是否相离,是输出Yes,否输出No. 训练指南上的分析: 1.任取红凸包上的一条线段和蓝凸包上的一条线段,判断二者是否相交.如果相交( ...
- UVA 10256 The Great Divide (凸包,多边形的位置关系)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34148 [思路] 凸包 求出红蓝点的凸包,剩下的问题就是判断两个凸 ...
- uva 10256 The Great Divide
题意:给定两个点集,一个红点集,另一个蓝点集,询问,能否找到一条直线能,使得任取一个红点和蓝点都在直线异侧. 思路:划分成两个凸包,一个红包,一个蓝包.两个凸包不相交不重合. 1.任取一个凸包中的点不 ...
- UVA 10256 The Great Divide(凸包划分)
The Great Divide Input: standard input Output: standard output Time Limit: 8 seconds Memory Limit: 3 ...
- UVA 10256 The Great Divide(点在多边形内)
The Great Divid [题目链接]The Great Divid [题目类型]点在多边形内 &题解: 蓝书274, 感觉我的代码和刘汝佳的没啥区别,可是我的就是wa,所以贴一发刘汝佳 ...
- UVa 10256 (判断两个凸包相离) The Great Divide
题意: 给出n个红点,m个蓝点.问是否存在一条直线使得红点和蓝点分别分布在直线的两侧,这些点不能再直线上. 分析: 求出两种点的凸包,如果两个凸包相离的话,则存在这样一条直线. 判断凸包相离需要判断这 ...
- 【暑假】[数学]UVa 10375 Choose and divide
UVa 10375 Choose and divide 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19601 思路 ...
- UVA - 10375 Choose and divide[唯一分解定理]
UVA - 10375 Choose and divide Choose and divide Time Limit: 1000MS Memory Limit: 65536K Total Subm ...
- 005推断两个字符串是否是变位词 (keep it up)
写一个函数推断两个字符串是否是变位词. 变位词(anagrams)指的是组成两个单词的字符同样,但位置不同的单词.比方说, abbcd和abcdb就是一对变位词 这也是简单的题. 我们能够排序然后对照 ...
随机推荐
- [RxJS] Creating Observable From Scratch
Get a better understanding of the RxJS Observable by implementing one that's similar from the ground ...
- 解决Fetching android sdk component information加载过久问题
安装完成后,如果直接启动,Android Studio会去获取 android sdk 组件信息,这个过程相当慢,还经常加载失败,导致Android Studio启动不起开.解决办法就是不去获取and ...
- AngularJs练习Demo7
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport&quo ...
- Oracle 账户被锁定
哎 每次安装oracle的时候总是忘了将用户解锁,结果就蛋疼了,从网上找到一个简单的解决方案 在CMD命令输出如下: sqlplus /nolog alert user system account ...
- 简单的LRU Cache设计与实现
要求: 设计并实现一个LRU缓存的数据结构,支持get和set操作 get(key):若缓存中存在key,返回对应的value,否则返回-1 set(key,value):若缓存中存在key,替换其v ...
- OFBiz中根据店铺获取产品可用库存的方法
1.[ProductStoreFacility]获得店铺绑定的仓库列表 2.遍历仓库,调用[getInventoryAvailableByFacility],传入[facilityId : facil ...
- xml解析,练习
<collection shelf="New Arrivals"><movie title="Enemy Behind"> < ...
- HBase -ROOT-和.META.表结构(region定位原理)
在HBase中,大部分的操作都是在RegionServer完成的,Client端想要插入,删除,查询数据都需要先找到相应的RegionServer.什么叫相应的RegionServer?就是管理你要操 ...
- HDU Today--hdu2112
HDU Today Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- 可以ping通,浏览器打不开网页 - 解决办法
网络故障表现为: 1.电脑显示网络连接正常,DNS配置和hosts配置均正常 2.cmd可以ping通网址,域名 3.所有浏览器无法打开网页,有道云笔记置灰,微信二维码刷新失败 解决办法: 管理员权限 ...