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. DataBase -- FUNCTION

    SQL拥有很多课用于计数和计算的内建函数. SELECT function(列) FROM 表 合计函数(Aggregate Functions) Aggregate函数的操作面向一系列的值,并返回一 ...

  2. 安徽师大附中%你赛day9 T3 贵 解题报告

    贵 问题描述 苟先生的狼狗大军没有追上富先生, 所以他把它们都解雇了, 决定去雇佣一些更好的狗, 不过狗可是很贵的.苟先生有 \(w\) 元钱, 有 \(n\) 条狗可以雇佣, 第 \(i\) 条狗有 ...

  3. 【BZOJ 3772】精神污染 主席树+欧拉序

    这道题的内存…………………真·精神污染……….. 这道题的思路很明了,我们就是要找每一个路径包含了多少其他路径那么就是找,有多少路径的左右端点都在这条路径上,对于每一条路径,我们随便选定一个端点作为第 ...

  4. 湖南大学第十四届ACM程序设计新生杯 E.Easy Problem

    E.Easy Problem Description: Zghh likes number, but he doesn't like writing problem description. So h ...

  5. AWS nat monitor and route switch script

    This script will monitor another NAT instance and take over its routes if communication with the oth ...

  6. MySQL 8.0.11(zip)安装及配置

    (1)下载MySQL8.0.11: (2)解压zip文件: 我解压到了D:/MySQL/mysql-8.0.11-winx64 (3)配置环境变量:   右键此电脑->属性 高级系统设置 环境变 ...

  7. python读写Excel文件_xlrd模块读取,xlwt模块写入

    一.安装xlrd模块和xlwt模块(服务器) 1. 下载xlrd模块和xlwt模块 到python官网http://pypi.python.org/pypi/xlrd下载模块.下载的文件例如:xlrd ...

  8. [POJ1845&POJ1061]扩展欧几里得应用两例

    扩展欧几里得是用于求解不定方程.线性同余方程和乘法逆元的常用算法. 下面是代码: function Euclid(a,b:int64;var x,y:int64):int64; var t:int64 ...

  9. [转载]解决clickonce不支持administer权限问题

    转自ClickOnce deployment vs. requestedExecutionLevel = requireAdministrator ClickOnce方式部署应用简单方便,估计很多人都 ...

  10. wiki1285

    2013-09-21 16:50 裸 //By BLADEVIL var n :longint; i :longint; x, y :longint; t, tot :longint; key, s, ...