提交地址:

题目:


pdf:https://uva.onlinejudge.org/external/102/10256.pdf

n个红点,m个蓝点,是否存在一条直线,使得任取一个红点和一个蓝点都在直线的异侧?这条直线不能穿过红点或者蓝点

解题思路:


先求出红点和蓝点的凸包,如果这两个凸包是相离的,那么一定能找到一个满足条件的直线,问题转化为判断两个凸包是否相离。

(1)任取一个红点(或者蓝点),如果这个红点(或者蓝点)都不在那一个凸包内(点在多边形内判定), 那么这两个凸包有可能相离。

(2)光满足条件(1)还不够,因为可能会出现下图这样的情况,所以还需要判断两个凸包的任意两条边之间是否相交。

(3)当凸包是一个点或者线段需要特判。

ac代码:


#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
const double eps = 1e-6;
const int maxn = 550;
int dcmp(double x)//精度三态函数(>0,<0,=0)
{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){}friend bool operator == (Point a, Point b){return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;}friend bool operator < (Point a, Point b){return a.x == b.x ? a.y < b.y : a.x < b.x;}
};
typedef Point Vector;Vector operator - (Vector a, Vector b)//向量减法
{return Vector(a.x - b.x, a.y - b.y);
}double Dot(Vector a, Vector b)//点积
{return a.x * b.x + a.y * b.y;
}
double Cross(Vector a, Vector b)//外积
{return a.x * b.y - a.y * b.x;
}bool Onsegment(Point p, Point a1, Point a2)
{return dcmp(Cross(a1 - p, a2 - p)) == 0 && dcmp(Dot(a1 - p, a2 - p)) < 0;
}
bool JudgeSegmentIntersect(Point A, Point B, Point C, Point D) //线段相交(包括端点)
{returndcmp(max(A.x, B.x) - min(C.x, D.x)) >= 0&& dcmp(max(C.x, D.x) - min(A.x, B.x)) >= 0&& dcmp(max(A.y, B.y) - min(C.y, D.y)) >= 0&& dcmp(max(C.y, D.y) - min(A.y, B.y)) >= 0&& dcmp(Cross(C - A, D - A)*Cross(C - B, D - B)) <= 0&& dcmp(Cross(A - C, B - C)*Cross(A - D, B - D)) <= 0;
}int isPointInPolygon(Point p, Point v[], int n)//n多边形顶点个数
{int wn = 0;for(int i = 0; i < n; i++)//多边形的端点从0开始存{if(Onsegment(p, v[i], v[(i+1)%n])) return -1;//在边界上int k = dcmp(Cross(v[(i+1)%n] - v[i], p-v[i]));int d1 = dcmp(v[i].y - p.y);int d2 = dcmp(v[(i+1)%n].y - p.y);//后两个条件确保射线能穿过多边形的这条边if(k>0 && d1<=0 && d2>0) wn++;//p在v[i]和v[(i+1)%n]向量左侧且y值在[v[i].y,v[(i+1)%n.y)if(k<0 && d2<=0 && d1>0) wn--;//右侧,且[v(i+1)%n.y, v[i].y)}if(wn!=0) return 1;//内部return 0;//外部
}int ConvexHull(Point *p, int n, Point* ch)//凸包,ch存结果
{sort(p, p+n);//先x后yint m = 0;//ch存最终的凸包顶点,下标从0开始for(int i = 0; i < n; i++){//m是待确定的while(m > 1 && dcmp(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 && dcmp(Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2])) <= 0) m--;//同样的方向ch[m++] = p[i];}if(n>1) m--;//m是凸包上的点数+1,相当于n,ch[m]和ch[0]相同,遍历的时候<m即可return m;
}Point p1[maxn], p2[maxn], ch1[maxn], ch2[maxn];
int n, m, m1, m2;
bool check()
{if(m1 == 1 && m2 == 1) return ch1[0] == ch2[0] ? false : true;else if(m1 == 1 && m2 == 2) return !Onsegment(ch1[0], ch2[0], ch2[1]);else if(m1 == 2 && m2 == 1) return !Onsegment(ch2[0], ch1[0], ch1[1]);else if(m1 == 2 && m2 == 2) return !JudgeSegmentIntersect(ch1[0], ch1[1], ch2[0], ch2[1]);else if(m1 == 1 && m2 > 2) return !isPointInPolygon(ch1[0], ch2, m2);else if(m2 == 1 && m1 > 2) return !isPointInPolygon(ch2[0], ch1, m1);else if(m1 == 2 && m2 > 2){for(int i = 0; i < m2; i++)if(JudgeSegmentIntersect(ch1[0], ch1[1], ch2[i], ch2[(i+1)%m2])) return false;//线段是否在另一个凸包的边上int d1 = isPointInPolygon(ch1[0], ch2, m2);if(d1 == -1 || d1 == 1) return false;int d2 = isPointInPolygon(ch1[1], ch2, m2);if(d2 == -1 || d2 == 1) return false;return true;}else if(m2 == 2 && m1 > 2){for(int i = 0; i < m1; i++)if(JudgeSegmentIntersect(ch2[0], ch2[1], ch1[i], ch1[(i+1)%m1])) return false;int d1 = isPointInPolygon(ch2[0], ch1, m1);if(d1 == -1 || d1 == 1) return false;int d2 = isPointInPolygon(ch2[1], ch1, m1);if(d2 == -1 || d2 == 1) return false;return true;}else//m1>2 m2>2{for(int i = 0; i < m1; i++)for(int j = 0; j < m2; j++)if(JudgeSegmentIntersect(ch1[i], ch1[(i+1)%m1], ch2[j], ch2[(j+1)%m2])) return false;for(int i = 0; i < m1; i++){int d = isPointInPolygon(ch1[i], ch2, m2);if(d == -1 || d == 1) return false;}for(int i = 0; i < m2; i++){int d = isPointInPolygon(ch2[i], ch1, m1);if(d == -1 || d == 1) return false;}return true;}}
int main()
{//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);while(scanf("%d %d",&n, &m)){if(n == 0 && m == 0) break;for(int i = 0; i < n; i++) scanf("%lf %lf", &p1[i].x, &p1[i].y);for(int i = 0; i < m; i++) scanf("%lf %lf", &p2[i].x, &p2[i].y);m1 = ConvexHull(p1, n, ch1);m2 = ConvexHull(p2, m, ch2);if(check()) printf("Yes\n");else printf("No\n");}return 0;
}

【UVA10256】The Great Divide(凸包相离判定)相关推荐

  1. 名词解释:失压、全失压、断相、失流、掉电(DL645-2007)

    出处:http://blog.163.com/steven_lucas/blog/static/16728550220113503413650/ 失压 loss of voltage 在三相(或单相) ...

  2. 永磁同步电机相序测量中遇到的问题及解决

    最近又参与测试了一台六相对称永磁同步电机的相序,记录测试过程如下: 在测试电机相序之前,我们要对测试对象有一个基本了解. 1.六相对称电机的六相相位及其合成磁链的方向如图1所示,也就是说,ABC与UV ...

  3. 数论六之计算几何干货——计算几何模板解释全集 及 模板检验训练场

    文章目录 点和向量及运算 直线和线段 求解点到直线的距离/点在直线上 求解点到线段的距离/点在线段上 求解两条线段是否相交 求解两直线的交点 多边形 求解多边形面积 求解多边形重心 求解判断定点与多边 ...

  4. 2018十二月刷题列表

    Preface \(2018\)年的尾巴,不禁感慨自己这一年的蜕变只能用蜕变来形容了. 而且老叶说我们今年没的参加清北冬令营可以参加CCF在广州二中举办的冬令营,只要联赛\(390+\)就应该可以报. ...

  5. 刷题常用模板 by flytosky2015

    声明模板: #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath& ...

  6. 做acm 需要学的算法

    做acm 需要学的算法 转一个搞ACM需要的掌握的算法.  要注意,ACM的竞赛性强,因此自己应该和自己的实际应用联系起来.  适合自己的才是好的,有的人不适合搞算法,喜欢系统架构,因此不要看到别人什 ...

  7. [转载]acm进阶之路

    第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码, 因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打  出来.  1.最短路(Floyd ...

  8. 从今开始,好好学习一下算法!

    ACM 进阶之路(转) 2007年12月30日 星期日 18:20 一般要做到50行以内的程序不用调试.100行以内的二分钟内调试成功.ACM主要是考算法的,主要时间是花在思考算法上,不是花在写程序与 ...

  9. ACM 网址和一些建议

    USACO http://ace.delos.com/usacogate 美国著名在线题库,专门为信息学竞赛选手准备 TJU http://acm.tongji.edu.cn/ 同济大学在线题库,唯一 ...

  10. ACM大量习题题库及建议培养计划

    ACM大量习题题库 ACM大量习题题库  现在网上有许多题库,大多是可以在线评测,所以叫做Online Judge.除了USACO是为IOI准备外,其余几乎全部是大学的ACM竞赛题库. USACO h ...

最新文章

  1. 计算机为什么找不到c盘d盘,电脑不显示是什么盘?是C盘还是D盘?怎么才能显示出来呢?...
  2. SAP WM中阶之存储类型上架策略I(Adding to existing stock)
  3. RabbitMQ分布式集群架构
  4. SideFX Houdini FX中文版
  5. 在全局中调用类的静态成员函数
  6. 如何成为python 数据分析师_如何七周成为数据分析师20:了解和掌握Python的函数...
  7. 高校计算机基础能力测试文字处理,高校计算机基础论文3篇(共8238字).doc
  8. 了解OPhone平台---OPhone平台架构和主要开发组件
  9. zabbix自动发现监控磁盘(iops和读写量)
  10. 分组查询最晚一条数据(ORACLE)
  11. 7-56 家庭房产 (25 分)
  12. iPhone质量成迷?被吴彦祖一箭射穿,却还能开机
  13. 【图像增强】python图像数据增强
  14. 知乎:学习分布式系统需要怎样的知识?
  15. 有乐窝一周精选(二)
  16. 维护机房服务器工作,机房维护(服务器搬迁方案).doc
  17. Android原生框架--Xui使用
  18. NoClassDefFoundError: ch/qos/logback/classic/spi/ThrowableProxy
  19. azw3电子书如何用安卓手机打开?
  20. FC6下chm文件阅读器chmsee的安装

热门文章

  1. html怎么快速收录,如何让网站快速收录?网站提高收录的10种方法
  2. java 天上掉东西游戏的源代码_【小游戏】前两天的小游戏终于调试成功了。。。。直接源代码...
  3. 上下相机贴合对位计算公式_ccd视觉自动对位贴合机主要应用在哪里?
  4. Spring bean注入之constructor-arg注入和property注入的区别
  5. rust木炭有用吗_如何看待 Rust 这门语言?
  6. mybatis中的mapper代理的应用
  7. Java中面向对象和面向过程的简单理解以及共同点和区别
  8. zabbix监控mysql集群_zabbix监控elasticsearch集群
  9. python人脸识别程序如何嵌入到app_开源|手把手教你用Python进行人脸识别(附源代码)...
  10. ORACLE 10G R1手工创建数据库步骤