怎么又没人写题解,那我来贡献一发好了。

题目意思很简单,平面上有两种颜色的点,问你能否求出一条直线使两种颜色的点完全分开。

首先我们考虑两个点集相离的充要条件,这两个点集的凸包必须相离。(很好证明或者画画图理解一下)

那么怎么判断两个凸包相离,考虑到这里的点的个数不多,我们可以用一种最暴力的方法。

枚举一个凸包上的所有点所有边,然后判断是否与另一个凸包相离即可。

点是否在多边形内?直接暴力转角法即可(不推荐射线法,好理解但不好写,精度不高)

边是否在多边形内,在两个凸包中分别枚举一条边,然后判断是否相交即可。

稍微注意一下精度问题即可,其实计算几何的题主要考验的就是代码的细节能力。

CODE

#include<cstdio>
#include<cmath>
#include<algorithm>
#define RI register int
using namespace std;
typedef double DB;
const int N=505;
const DB EPS=1e-10;
inline int dcmp(DB x)
{
if (fabs(x)<EPS) return 0; return x<0?-1:1;
}
struct Point
{
DB x,y;
Point(DB X=0,DB Y=0) { x=X; y=Y; }
inline friend bool operator <(Point A,Point B)
{
return dcmp(A.x-B.x)<0||(!dcmp(A.y-B.y)&&dcmp(A.y-B.y)<0);
}
inline friend bool operator ==(Point A,Point B)
{
return !dcmp(A.x-B.x)&&!dcmp(A.y-B.y);
}
}a[N],b[N],cov_a[N],cov_b[N]; int n,m,cnt_a,cnt_b; DB x,y;
typedef Point Vector;
inline Vector operator -(Point A,Point B) { return Vector(A.x-B.x,A.y-B.y); }
class Computation_Geometry
{
private:
inline DB Dot(Vector A,Vector B)
{
return A.x*B.x+A.y*B.y;
}
inline DB Cross(Vector A,Vector B)
{
return A.x*B.y-A.y*B.x;
}
inline bool OnSegment(Point p,Point A,Point B)
{
return !dcmp(Cross(A-p,B-p))&&dcmp(Dot(A-p,B-p))<0;
}
inline bool IsPointInPolygon(Point p,Point *a,int n)
{
int t=0; for (RI i=1;i<=n;++i)
{
Point p1=a[i],p2=a[(i+1)%n+1];
if (p1==p||p2==p||OnSegment(p,p1,p2)) return 1;
int ret=dcmp(Cross(p2-p1,p-p1)),d1=dcmp(p1.y-p.y),d2=dcmp(p2.y-p.y);
if (ret>0&&d1<=0&&d2>0) ++t; if (ret<0&&d2<=0&&d1>0) --t;
}
return t!=0;
}
inline bool SegmentProperIntersection(Point A,Point B,Point C,Point D)
{
DB c1=Cross(B-A,C-A),c2=Cross(B-A,D-A),c3=Cross(D-C,A-C),c4=Cross(D-C,B-C);
return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;
}
public:
inline int ConvexHull(Point *a,int n,Point *p)
{
sort(a+1,a+n+1); n=unique(a+1,a+n+1)-a-1; RI i,top=0;
for (i=1;i<=n;++i)
{
while (top>1&&dcmp(Cross(p[top]-p[top-1],a[i]-p[top]))<=0) --top;
p[++top]=a[i];
}
int t=top; for (i=n-1;i;--i)
{
while (top>t&&dcmp(Cross(p[top]-p[top-1],a[i]-p[top]))<=0) --top;
p[++top]=a[i];
}
if (n>1) --top; return top;
}
inline bool ConvexPolygonDisjoint(Point *a,int n,Point *b,int m)
{
RI i,j; for (i=1;i<=n;++i) if (IsPointInPolygon(a[i],b,m)) return 1;
for (i=1;i<=m;++i) if (IsPointInPolygon(b[i],a,n)) return 1;
for (i=1;i<=n;++i) for (j=1;j<=m;++j)
if (SegmentProperIntersection(a[i],a[i%n+1],b[j],b[j%m+1])) return 1;
return 0;
}
}G;
int main()
{
while (scanf("%d%d",&n,&m),n&&m)
{
RI i; for (i=1;i<=n;++i) scanf("%lf%lf",&x,&y),a[i]=Point(x,y);
for (i=1;i<=m;++i) scanf("%lf%lf",&x,&y),b[i]=Point(x,y);
cnt_a=G.ConvexHull(a,n,cov_a); cnt_b=G.ConvexHull(b,m,cov_b);
puts(G.ConvexPolygonDisjoint(cov_a,cnt_a,cov_b,cnt_b)?"No":"Yes");
};
return 0;
}

UVA10256 The Great Divide的更多相关文章

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

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

  2. [LeetCode] Divide Two Integers 两数相除

    Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...

  3. Pairwise Sum and Divide 51nod

      1305 Pairwise Sum and Divide 题目来源: HackerRank 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题  收藏  关注 有这样 ...

  4. Conquer and Divide经典例子之Strassen算法解决大型矩阵的相乘

    在通过汉诺塔问题理解递归的精髓中我讲解了怎么把一个复杂的问题一步步recursively划分了成简单显而易见的小问题.其实这个解决问题的思路就是算法中常用的divide and conquer, 这篇 ...

  5. UVA - 10375 Choose and divide[唯一分解定理]

    UVA - 10375 Choose and divide Choose and divide Time Limit: 1000MS   Memory Limit: 65536K Total Subm ...

  6. [leetcode] 29. divide two integers

    这道题目一直不会做,因为要考虑的corner case 太多. 1. divisor equals 0. 2. dividend equals 0. 3. Is the result negative ...

  7. Leetcode Divide Two Integers

    Divide two integers without using multiplication, division and mod operator. 不用乘.除.求余操作,返回两整数相除的结果,结 ...

  8. uva10375 Choose and Divide(唯一分解定理)

    uva10375 Choose and Divide(唯一分解定理) 题意: 已知C(m,n)=m! / (n!*(m-n!)),输入整数p,q,r,s(p>=q,r>=s,p,q,r,s ...

  9. 51nod1305 Pairwise Sum and Divide

    题目链接:51nod 1305 Pairwise Sum and Divide 看完题我想都没想就直接暴力做了,AC后突然就反应过来了... Floor( (a+b)/(a*b) )=Floor( ( ...

随机推荐

  1. ThreadPoolExecutor 线程池的源码解析

    1.背景介绍 上一篇从整体上介绍了Executor接口,从上一篇我们知道了Executor框架的最顶层实现是ThreadPoolExecutor类,Executors工厂类中提供的newSchedul ...

  2. 「Android」GreenDao

    译文 版本:greenDAO 3.2.2 官网:http://greenrobot.org/greendao/ GitHub:https://github.com/greenrobot/greenDA ...

  3. js数组的用法以及数组根据下标(数值或字符)移除元素

    1.创建数组var array = new Array();var array = new Array(size);//指定数组的长度var array = new Array(item1,item2 ...

  4. 转载:如何在Ubuntu 18.04上使用UFW设置防火墙

    https://blog.csdn.net/u013068789/article/details/82051943 介绍 UFW或Uncomplicated Firewall是iptables一个接口 ...

  5. 利用Selenium爬取淘宝商品信息

    一.  Selenium和PhantomJS介绍 Selenium是一个用于Web应用程序测试的工具,Selenium直接运行在浏览器中,就像真正的用户在操作一样.由于这个性质,Selenium也是一 ...

  6. python如何实现类似php的引用赋值

    直接放代码,有注释,就不解析了 # ############################ # 改变一个变量的值,与之有关系的变量的值也会相等变化 # 类似php的引用赋值,宏观来看 # ##### ...

  7. SQL server 导出平面文件时出错: The code page on Destination - 3_txt.Inputs[Flat File Destination Input].Columns[UserId] is 936 and is required to be 1252.

    我在导出平面文件时:Error 0xc00470d4: Data Flow Task 1: The code page on Destination - 3_txt.Inputs[Flat File ...

  8. 自动化测试基础篇--Selenium select下拉框

    摘自https://www.cnblogs.com/sanzangTst/p/7681523.html 一.什么是下拉框 下拉框是多项选择项,选择其中一种,类似下面(以百度搜索设置为例) 源代码如下所 ...

  9. mysql 数据库安装

    一.Mysql的安装 1. 安装mysql-server服务端 版本5.7.19-0ubuntu0.16.04.1 目前可以下载的版本: 5.5 5.6 5.7 8.0 测试版 输入:(我这里不需要客 ...

  10. 关于svn上传.classpath等问题

    1. svn版本:客户端版本与服务器版本 要尽量适配. 2. svn管理项目:有人将.classpath, .project, .mymetadata, .myumldata等文件也纳入到版本控制,如 ...