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

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

  1. #include<cstdio>
  2. #include<vector>
  3. #include<cmath>
  4. #include<algorithm>
  5. using namespace std;
  6.  
  7. const double eps = 1e-10;
  8. double dcmp(double x) {
  9. if(fabs(x) < eps) return 0;
  10. else return x < 0 ?
  11.  
  12. -1 : 1;
  13. }
  14.  
  15. struct Point {
  16. double x, y;
  17. Point(double x=0, double y=0):x(x),y(y) {}
  18. };
  19.  
  20. typedef Point Vector;
  21.  
  22. Vector operator - (const Point& A, const Point& B) {
  23. return Vector(A.x-B.x, A.y-B.y);
  24. }
  25.  
  26. double Cross(const Vector& A, const Vector& B) {
  27. return A.x*B.y - A.y*B.x;
  28. }
  29.  
  30. double Dot(const Vector& A, const Vector& B) {
  31. return A.x*B.x + A.y*B.y;
  32. }
  33.  
  34. bool operator < (const Point& p1, const Point& p2) {
  35. return p1.x < p2.x || (p1.x == p2.x && p1.y < p2.y);
  36. }
  37.  
  38. bool operator == (const Point& p1, const Point& p2) {
  39. return p1.x == p2.x && p1.y == p2.y;
  40. }
  41.  
  42. bool SegmentProperIntersection(const Point& a1, const Point& a2, const Point& b1, const Point& b2) {
  43. double c1 = Cross(a2-a1,b1-a1), c2 = Cross(a2-a1,b2-a1),
  44. c3 = Cross(b2-b1,a1-b1), c4=Cross(b2-b1,a2-b1);
  45. return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
  46. }
  47.  
  48. bool OnSegment(const Point& p, const Point& a1, const Point& a2) {
  49. return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0;
  50. }
  51.  
  52. // 点集凸包
  53. // 假设不希望在凸包的边上有输入点,把两个 <= 改成 <
  54. // 假设不介意点集被改动,能够改成传递引用
  55. vector<Point> ConvexHull(vector<Point> p) {
  56. // 预处理,删除反复点
  57. sort(p.begin(), p.end());
  58. p.erase(unique(p.begin(), p.end()), p.end());
  59.  
  60. int n = p.size();
  61. int m = 0;
  62. vector<Point> ch(n+1);
  63. for(int i = 0; i < n; i++) {
  64. while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
  65. ch[m++] = p[i];
  66. }
  67. int k = m;
  68. for(int i = n-2; i >= 0; i--) {
  69. while(m > k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
  70. ch[m++] = p[i];
  71. }
  72. if(n > 1) m--;
  73. ch.resize(m);
  74. return ch;
  75. }
  76.  
  77. int IsPointInPolygon(const Point& p, const vector<Point>& poly) {
  78. int wn = 0;
  79. int n = poly.size();
  80. for(int i=0; i<n; ++i) {
  81. const Point& p1 = poly[i];
  82. const Point& p2 = poly[(i+1)%n];
  83. if(p1 == p || p2 == p || OnSegment(p, p1, p2)) return -1;//在边界上
  84. int k = dcmp(Cross(p2-p1, p-p1));
  85. int d1 = dcmp(p1.y - p.y);
  86. int d2 = dcmp(p2.y - p.y);
  87. if(k > 0 && d1 <= 0 && d2 > 0) wn++;
  88. if(k < 0 && d2 <= 0 && d1 > 0) wn--;
  89. }
  90. if(wn != 0) return 1;
  91. return 0;
  92. }
  93.  
  94. bool ConvexPolygonDisjoint(const vector<Point> ch1, const vector<Point> ch2) {
  95. int c1 = ch1.size();
  96. int c2 = ch2.size();
  97. for(int i=0; i<c1; ++i)
  98. if(IsPointInPolygon(ch1[i], ch2) != 0) return false;
  99. for(int i=0; i<c2; ++i)
  100. if(IsPointInPolygon(ch2[i], ch1) != 0) return false;
  101. for(int i=0; i<c1; ++i)
  102. for(int j=0; j<c2; ++j)
  103. if(SegmentProperIntersection(ch1[i], ch1[(i+1)%c1], ch2[j], ch2[(j+1)%c2])) return false;
  104. return true;
  105. }
  106.  
  107. int main() {
  108. int n, m;
  109. while(scanf("%d%d", &n, &m) == 2 && n > 0 && m > 0) {
  110. vector<Point> P1, P2;
  111. double x, y;
  112. for(int i = 0; i < n; i++) {
  113. scanf("%lf%lf", &x, &y);
  114. P1.push_back(Point(x, y));
  115. }
  116. for(int i = 0; i < m; i++) {
  117. scanf("%lf%lf", &x, &y);
  118. P2.push_back(Point(x, y));
  119. }
  120. if(ConvexPolygonDisjoint(ConvexHull(P1), ConvexHull(P2)))
  121. printf("Yes\n");
  122. else
  123. printf("No\n");
  124. }
  125. return 0;
  126. }

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. 辛星解读mysql的用户管理

    可能做开发的多半不太关注这方面,可是要说到做运维.那就不能不关注了.由于我们都知道,root的权限太大了.不是随便能用的.我们平时最好用一些比較低的权限的用户.这样会让我们的安全性大大提高,也能防止我 ...

  2. [CSAPP笔记][第十一章网络编程]

    第十一章 网络编程 我们需要理解基本的客户端-服务端编程模型,以及如何编写使用因特网提供的服务的客户端-服务端程序. 最后,我们将把所有这些概念结合起来,开发一个小的但功能齐全的Web服务器,能够为真 ...

  3. iOS会议和组织

    全世界有许多iOS会议和组织,如果你没有机会去参加,知道他们的存在和向他们学习对你也是有益的.事实上,他们中有些提供免费的幻灯片.视频,有用资料等,所以你不能够忽视他们. 有一些会议的主题并不仅仅关于 ...

  4. shell常用命令的用法

    1. 如何把 /etc/passwd 中用户uid 大于500 的行给打印出来?awk -F ':' '$3>500' /etc/passwd 2. awk中 NR,NF两个变量表示什么含义?N ...

  5. WebApi2官网学习记录---单元测试

    如果没有对应的web api模板,首先使用nuget进行安装 例子1: ProductController 是以硬编码的方式使用StoreAppContext类的实例,可以使用依赖注入模式,在外部指定 ...

  6. UIScrollView的属性

    属性 作用 CGPoint contentOffSet 监控目前滚动的位置 CGSize contentSize 滚动范围的大小 UIEdgeInsets contentInset 视图在scroll ...

  7. Selenium webdriver 截图 太长截不全的问题

    Selenium webdriver 截图 太长截不全的问题 1.环境 selenium webdriver.net 2.46.0.0 + firefox 37.0.1 + win 8.1 2.问题 ...

  8. ashx ajax 与 自定义javascript函数

    1.getUserPower为自定义javascript函数 获取权限  (1).ashx 处理程序的相对地址(必须是相对地址)  (2).au 权限名称  (3).classname 类名  (4) ...

  9. 树状dp ural1018

    #include<stdio.h> #include<string.h> #include <iostream> using namespace std; ; in ...

  10. dedecms likearticle 调用附加表的字段调用方式

    [field:id runphp='yes'] $aid = @me; $row = $GLOBALS['dsql']->GetOne("Select 字段名 From `dede_a ...