题目链接:POJ 3805

Problem Description

Numbers of black and white points are placed on a plane. Let’s imagine that a straight line of infinite length is drawn on the plane. When the line does not meet any of the points, the line divides these points into two groups. If the division by such a line results in one group consisting only of black points and the other consisting only of white points, we say that theline “separates black and white points”.

Let’s see examples in Figure 3. In the leftmost example, you can easily find that the black and white points can be perfectly separated by the dashed line according to their colors. In the remaining three examples, there exists no such straight line that gives such a separation.

In this problem, given a set of points with their colors and positions, you are requested to decide whether there exists a straight line that separates black and white points.

Input

The input is a sequence of datasets, each of which is formatted as follows.

  1. n m
  2. x1 y1
  3. .
  4. .
  5. .
  6. xn yn
  7. xn+1 yn+1
  8. .
  9. .
  10. .
  11. xn+m yn+m

The first line contains two positive integers separated by a single space; n is the number of black points, and m is the number of white points. They are less than or equal to 100. Then n + m lines representing the coordinates of points follow. Each line contains two integers xi and yi separated by a space, where (xi, yi) represents the x-coordinate and the y-coordinate of the i-th point. The color of the i-th point is black for 1 <= i <= n, and is white for n + 1 <= i <= n + m.

All the points have integral x- and y-coordinate values between 0 and 10000 inclusive. You can also assume that no two points have the same position.

The end of the input is indicated by a line containing two zeros separated by a space.

Output

For each dataset, output “YES” if there exists a line satisfying the condition. If not, output “NO”. In either case, print it in one line for each input dataset.

Sample Input

  1. 3 3
  2. 100 700
  3. 200 200
  4. 600 600
  5. 500 100
  6. 500 300
  7. 800 500
  8. 3 3
  9. 100 300
  10. 400 600
  11. 400 100
  12. 600 400
  13. 500 900
  14. 300 300
  15. 3 4
  16. 300 300
  17. 500 300
  18. 400 600
  19. 100 100
  20. 200 900
  21. 500 900
  22. 800 100
  23. 1 2
  24. 300 300
  25. 100 100
  26. 500 500
  27. 1 1
  28. 100 100
  29. 200 100
  30. 2 2
  31. 0 0
  32. 500 700
  33. 1000 1400
  34. 1500 2100
  35. 2 2
  36. 0 0
  37. 1000 1000
  38. 1000 0
  39. 0 1000
  40. 3 3
  41. 0 100
  42. 4999 102
  43. 10000 103
  44. 5001 102
  45. 10000 102
  46. 0 101
  47. 3 3
  48. 100 100
  49. 200 100
  50. 100 200
  51. 0 0
  52. 400 0
  53. 0 400
  54. 3 3
  55. 2813 1640
  56. 2583 2892
  57. 2967 1916
  58. 541 3562
  59. 9298 3686
  60. 7443 7921
  61. 0 0

Sample Output

  1. YES
  2. NO
  3. NO
  4. NO
  5. YES
  6. YES
  7. NO
  8. NO
  9. NO
  10. YES

Solution

题意

平面上有一些白点和黑点,问是否存在一条直线能把两类点分开。

题解

模板题。

详见 UVA 10256 The Great Divide (判断凸包相交)

Code

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <cmath>
  6. using namespace std;
  7. const double eps = 1e-8;
  8. const double pi = acos(-1.0);
  9. class Point {
  10. public:
  11. double x, y;
  12. Point(double x = 0, double y = 0) : x(x), y(y) {}
  13. Point operator+(Point a) {
  14. return Point(a.x + x, a.y + y);
  15. }
  16. Point operator-(Point a) {
  17. return Point(x - a.x, y - a.y);
  18. }
  19. bool operator<(const Point &a) const {
  20. if (x == a.x)
  21. return y < a.y;
  22. return x < a.x;
  23. }
  24. bool operator==(const Point &a) const {
  25. if (fabs(x - a.x) < eps && fabs(y - a.y) < eps)
  26. return 1;
  27. return 0;
  28. }
  29. double length() {
  30. return sqrt(x * x + y * y);
  31. }
  32. };
  33. typedef Point Vector;
  34. double cross(Vector a, Vector b) {
  35. return a.x * b.y - a.y * b.x;
  36. }
  37. double dot(Vector a, Vector b) {
  38. return a.x * b.x + a.y * b.y;
  39. }
  40. bool isclock(Point p0, Point p1, Point p2) {
  41. Vector a = p1 - p0;
  42. Vector b = p2 - p0;
  43. if (cross(a, b) < -eps)
  44. return true;
  45. return false;
  46. }
  47. double getDistance(Point a, Point b) {
  48. return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2));
  49. }
  50. typedef vector<Point> Polygon;
  51. Polygon Andrew(Polygon s) {
  52. Polygon u, l;
  53. if(s.size() < 3) return s;
  54. sort(s.begin(), s.end());
  55. u.push_back(s[0]);
  56. u.push_back(s[1]);
  57. l.push_back(s[s.size() - 1]);
  58. l.push_back(s[s.size() - 2]);
  59. for(int i = 2 ; i < s.size() ; ++i) {
  60. for(int n = u.size() ; n >= 2 && !isclock(u[n - 2], u[n - 1], s[i]); --n) {
  61. u.pop_back();
  62. }
  63. u.push_back(s[i]);
  64. }
  65. for(int i = s.size() - 3 ; i >= 0 ; --i) {
  66. for(int n = l.size() ; n >=2 && !isclock(l[n-2],l[n-1],s[i]); --n) {
  67. l.pop_back();
  68. }
  69. l.push_back(s[i]);
  70. }
  71. for(int i = 1 ; i < u.size() - 1 ; i++) l.push_back(u[i]);
  72. return l;
  73. }
  74. int dcmp(double x) {
  75. if (fabs(x) <= eps)
  76. return 0;
  77. return x > 0 ? 1 : -1;
  78. }
  79. // 判断点在线段上
  80. bool OnSegment(Point p, Point a1, Point a2) {
  81. return dcmp(cross(a1 - p, a2 - p)) == 0 && dcmp(dot(a1 - p, a2 - p)) < 0;
  82. }
  83. // 判断线段相交
  84. bool Intersection(Point a1, Point a2, Point b1, Point b2) {
  85. double c1 = cross(a2 - a1, b1 - a1), c2 = cross(a2 - a1, b2 - a1),
  86. c3 = cross(b2 - b1, a1 - b1), c4 = cross(b2 - b1, a2 - b1);
  87. return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
  88. }
  89. // 判断点在凸包内
  90. int isPointInPolygon(Point p, vector<Point> s) {
  91. int wn = 0, cc = s.size();
  92. for (int i = 0; i < cc; i++) {
  93. Point p1 = s[i];
  94. Point p2 = s[(i + 1) % cc];
  95. if (p1 == p || p2 == p || OnSegment(p, p1, p2)) return -1;
  96. int k = dcmp(cross(p2 - p1, p - p1));
  97. int d1 = dcmp(p1.y - p.y);
  98. int d2 = dcmp(p2.y - p.y);
  99. if (k > 0 && d1 <= 0 && d2 > 0) wn++;
  100. if (k < 0 && d2 <= 0 && d1 > 0) wn--;
  101. }
  102. if (wn != 0) return 1;
  103. return 0;
  104. }
  105. void solve(Polygon s1, Polygon s2) {
  106. int c1 = s1.size(), c2 = s2.size();
  107. for(int i = 0; i < c1; ++i) {
  108. if(isPointInPolygon(s1[i], s2)) {
  109. printf("NO\n");
  110. return;
  111. }
  112. }
  113. for(int i = 0; i < c2; ++i) {
  114. if(isPointInPolygon(s2[i], s1)) {
  115. printf("NO\n");
  116. return;
  117. }
  118. }
  119. for (int i = 0; i < c1; i++) {
  120. for (int j = 0; j < c2; j++) {
  121. if (Intersection(s1[i], s1[(i + 1) % c1], s2[j], s2[(j + 1) % c2])) {
  122. printf("NO\n");
  123. return;
  124. }
  125. }
  126. }
  127. printf("YES\n");
  128. }
  129. int main() {
  130. int n, m;
  131. while (cin >> n >> m) {
  132. if(n == 0 && m == 0) break;
  133. Polygon s1, s2;
  134. for (int i = 0; i < n; ++i) {
  135. double x1, x2;
  136. scanf("%lf%lf", &x1, &x2);
  137. s1.push_back(Point(x1, x2));
  138. }
  139. for (int i = 0; i < m; ++i) {
  140. double x1, x2;
  141. scanf("%lf%lf", &x1, &x2);
  142. s2.push_back(Point(x1, x2));
  143. }
  144. if(s1.size()) s1 = Andrew(s1);
  145. if(s2.size()) s2 = Andrew(s2);
  146. solve(s1, s2);
  147. }
  148. return 0;
  149. }

POJ 3805 Separate Points (判断凸包相交)的更多相关文章

  1. HDU 6590 Code (判断凸包相交)

    2019 杭电多校 1 1013 题目链接:HDU 6590 比赛链接:2019 Multi-University Training Contest 1 Problem Description Aft ...

  2. POJ 3449 Geometric Shapes 判断多边形相交

    题意不难理解,给出多个多边形,输出多边形间的相交情况(嵌套不算相交),思路也很容易想到.枚举每一个图形再枚举每一条边 恶心在输入输出,不过还好有sscanf(),不懂可以查看cplusplus网站 根 ...

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

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

  4. POJ 2653 Pick-up sticks (判断线段相交)

    Pick-up sticks Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 10330   Accepted: 3833 D ...

  5. [poj] 1066 Treasure Hunt || 判断直线相交

    原题 在金字塔内有一个宝藏p(x,y),现在要取出这个宝藏. 在金字塔内有许多墙,为了进入宝藏所在的房间必须把墙炸开,但是炸墙只能炸每个房间墙的中点. 求将宝藏运出城堡所需要的最小炸墙数. 判断点和直 ...

  6. POJ 3449 Geometric Shapes(判断几个不同图形的相交,线段相交判断)

    Geometric Shapes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 1243   Accepted: 524 D ...

  7. POJ 1584 A Round Peg in a Ground Hole[判断凸包 点在多边形内]

    A Round Peg in a Ground Hole Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6682   Acc ...

  8. UVALive7461 - Separating Pebbles 判断两个凸包相交

    //UVALive7461 - Separating Pebbles 判断两个凸包相交 #include <bits/stdc++.h> using namespace std; #def ...

  9. POJ 2826 An Easy Problem? 判断线段相交

    POJ 2826 An Easy Problem?! -- 思路来自kuangbin博客 下面三种情况比较特殊,特别是第三种 G++怎么交都是WA,同样的代码C++A了 #include <io ...

随机推荐

  1. openlayers中单击获取要素

    openlayers中单击获取要素 分类专栏: GIS 总结 OpenLayers   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接: ...

  2. Jeecg_Jflow整合记录

    系统组织机构 t_s_deparselect * from t_s_departselect * from t_s_depart where id='402888fd6a8c24e9016a8c531 ...

  3. upc组队赛6 Bumped!【最短路】

    Bumped! 题目描述 Peter returned from the recently held ACM ICPC World finals only to find that his retur ...

  4. VC的小工具查询exe的依赖

    查看程序或动态库所依赖的动态库 dumpbin /dependents  abc.exe 查看动态库的输出函数 dumpbin /exports abc.dll

  5. 转 Jmeter参数化--Post请求的Post body 参数化

    2018年01月22日 15:40:58 java2013liu 阅读数:2361收起 个人分类: Jemter   一.使用body data设置参数: 1,首先,使用Fiddler录制post请求 ...

  6. FrameWork内核解析之布局加载与资源系统(三)

    阿里P7Android高级架构进阶视频免费学习请点击:https://space.bilibili.com/474380680本篇文章将继续从以下两个内容来介绍布局加载与资源系统: [ LayoutM ...

  7. v-distpicker 一个好用的三级联动的插件

    // 引入插件npm install v-distpicker --save import VDistpicker from 'v-distpicker' Vue.component('v-distp ...

  8. H5 IOS 虚拟键盘不回落的问题

    在 H5 页面中,会发现在高版本的 IOS 系统中(ios12以上)和微信版本6.7.x以上,都会发现 input 等输入框,输入内容之后发现虚拟键盘消失,但是页面出现大面积白框. 解决办法(最后加上 ...

  9. Python之os.path.join()

    os.path.join()函数用于路径拼接文件路径. os.path.join()函数中可以传入多个路径: 会从第一个以”/”开头的参数开始拼接,之前的参数全部丢弃. 以上一种情况为先.在上一种情况 ...

  10. LinkButton(按钮)组件

    一.//class加载方式 <div id="pos" class="easyui-linkbutton">按钮</div> 二.js加 ...