uva10256

题意

平面上存在两种颜色的点,问是否存在一条直线,使得任取一个红点和一个蓝点都在直线的异侧,这条直线不经过任何点。

分析

对每种颜色的点求一发凸包,问题等价于判断两个多边形是否相交或相切。

  1. 判断是否有边相交
  2. 判断是否有点在另一个多边形内或边上

code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const double INF = 1e18;
const int MAXN = 6e2 + 10;
const double EPS = 1e-9;
int Sgn(double x) {
if(fabs(x) < EPS) return 0;
return x < 0 ? -1 : 1;
}
struct Point {
double x, y;
Point(double x = 0, double y = 0) : x(x), y(y) {}
bool operator < (const Point& p1) const {
if(x == p1.x) return y < p1.y;
return x < p1.x;
}
void read_point() {
scanf("%lf%lf", &x, &y);
}
};
typedef Point Vector;
double Dot(Point p1, Point p2) {
return p1.x * p2.x + p1.y * p2.y;
}
double Cross(Point p1, Point p2) {
return p1.x * p2.y - p1.y * p2.x;
}
Point operator - (Point p1, Point p2) {
return Point(p1.x - p2.x, p1.y - p2.y);
}
// 判断点是否在线段上(不包括端点)
bool OnSegment(Point P, Point a1, Point a2) {
Vector v1 = a1 - P, v2 = a2 - P;
return Sgn(Cross(v1, v2)) == 0 && Sgn(Dot(v1, v2)) < 0;
}
bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2) {
double c1 = Cross(a2 - a1, b1 - a1), c2 = Cross(a2 - a1, b2 - a1);
double c3 = Cross(b2 - b1, a1 - b1), c4 = Cross(b2 - b1, a2 - b1);
return Sgn(c1) * Sgn(c2) < 0 && Sgn(c3) * Sgn(c4) < 0;
}
int ConvexHull(Point* p, int n, Point* ch) {
sort(p, p + n);
int m = 0;
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--;
return m;
}
//判定点P是否在多边形内部
int isPointInPolygon(Point P, Point* Poly, int n) {
int wn = 0;
for(int i = 0; i < n; ++i) {
if(OnSegment(P, Poly[i], Poly[(i + 1) % n])) return -1; //在边界上
int k = Sgn(Cross(Poly[(i + 1) % n] - Poly[i], P - Poly[i]));
int d1 = Sgn(Poly[i].y - P.y);
int d2 = Sgn(Poly[(i + 1) % n].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; //外部
} Point p1[MAXN], p2[MAXN], ch1[MAXN], ch2[MAXN];
int main() {
int n, m;
while(~scanf("%d%d", &n, &m) && (n + m)) {
for(int i = 0; i < n; i++) {
p1[i].read_point();
}
for(int i = 0; i < m; i++) {
p2[i].read_point();
}
int nn = ConvexHull(p1, n, ch1);
int mm = ConvexHull(p2, m, ch2);
int flg = 1;
for(int i = 0; i < nn; i++) {
if(isPointInPolygon(ch1[i], ch2, mm)) flg = 0;
for(int j = 0; j < mm; j++) {
if(SegmentProperIntersection(ch1[i], ch1[(i + 1) % nn], ch2[j], ch2[(j + 1) % mm])) {
flg = 0;
}
}
}
for(int i = 0; i < mm; i++) {
if(isPointInPolygon(ch2[i], ch1, nn)) flg = 0;
}
puts(flg ? "Yes" : "No");
}
return 0;
}

uva10256的更多相关文章

  1. 【题解】The Great Divide [Uva10256]

    [题解]The Great Divide [Uva10256] 传送门:\(\text{The Great Divide [Uva10256]}\) [题目描述] 输入多组数据,每组数据给定 \(n\ ...

  2. uva10256(计算几何)

    省选前练模板系列: #include<cmath> #include<cstdio> #include<cstring> #include<iostream& ...

  3. UVA10256 The Great Divide

    怎么又没人写题解,那我来贡献一发好了. 题目意思很简单,平面上有两种颜色的点,问你能否求出一条直线使两种颜色的点完全分开. 首先我们考虑两个点集相离的充要条件,这两个点集的凸包必须相离.(很好证明或者 ...

随机推荐

  1. c# 以多个字符串分隔字符串数据 分组 分隔 split 正则分组

    string str="aaa[##]ccc[##]ddd[##]bb" Regex regex=new Regex("[##]");//以 [##] 分割 s ...

  2. hdu 6203 ping ping ping(LCA+树状数组)

    hdu 6203 ping ping ping(LCA+树状数组) 题意:给一棵树,有m条路径,问至少删除多少个点使得这些路径都不连通 \(1 <= n <= 1e4\) \(1 < ...

  3. 安徽师大附中%你赛day3T1 怜香惜玉 解题报告

    怜香惜玉 题意: 已知 \(f(x)=\frac{2 \times \sum_{(i,x)=1}^x i}{φ(x)}\) 先给定数据组数\(t\)和\(k\) 每组数据给出\(n\),求\(\sum ...

  4. vue父组件中修改子组件样式

    1. 使用全局样式 <style> /* 全局样式 */ </style> <style scoped> /* 本地样式 */ </style> 2. ...

  5. YUI Compressor是如何压缩JS代码的?

    YUI Compressor 压缩 JavaScript 的内容包括: 移除注释 移除额外的空格 细微优化 标识符替换(Identifier Replacement) YUI Compressor 包 ...

  6. ldconfig用法小记

    By francis_hao    Aug 4,2017   ldconfig:配置运行时动态链接库 概述 /sbin/ldconfig [ -nNvXV ] [ -f conf ] [ -C cac ...

  7. PropertiesConfiguration的用法

    PropertiesConfiguration是一个配置文件的加载工具类,封装了从配置文件里获取值并转化为基本数据类型的方法. 使用org.apache.commons.configuration2中 ...

  8. 两数之和 [ leetcode ]

    原题地址:https://leetcode-cn.com/articles/two-sum/ 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元 ...

  9. ansible+docker

    1.准备镜像: 1007 docker run -itd --name client2 ff37bc5ab732 1008 docker run -itd --name client ff37bc5a ...

  10. tomcat 配置文件中设置JAVA_HOME

    Tomcat默认情况下会用系统的环境变量中找到JAVA_HOME和JRE_HOME.但是有的时候我们需要不同版本的JDK共存. 可以在${TOMCAT_HOME}/bin/setclasspath.b ...