UVA10256 The Great Divide
怎么又没人写题解,那我来贡献一发好了。
题目意思很简单,平面上有两种颜色的点,问你能否求出一条直线使两种颜色的点完全分开。
首先我们考虑两个点集相离的充要条件,这两个点集的凸包必须相离。(很好证明或者画画图理解一下)
那么怎么判断两个凸包相离,考虑到这里的点的个数不多,我们可以用一种最暴力的方法。
枚举一个凸包上的所有点和所有边,然后判断是否与另一个凸包相离即可。
点是否在多边形内?直接暴力转角法即可(不推荐射线法,好理解但不好写,精度不高)
边是否在多边形内,在两个凸包中分别枚举一条边,然后判断是否相交即可。
稍微注意一下精度问题即可,其实计算几何的题主要考验的就是代码的细节能力。
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的更多相关文章
- 【题解】The Great Divide [Uva10256]
[题解]The Great Divide [Uva10256] 传送门:\(\text{The Great Divide [Uva10256]}\) [题目描述] 输入多组数据,每组数据给定 \(n\ ...
- [LeetCode] Divide Two Integers 两数相除
Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...
- Pairwise Sum and Divide 51nod
1305 Pairwise Sum and Divide 题目来源: HackerRank 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 收藏 关注 有这样 ...
- Conquer and Divide经典例子之Strassen算法解决大型矩阵的相乘
在通过汉诺塔问题理解递归的精髓中我讲解了怎么把一个复杂的问题一步步recursively划分了成简单显而易见的小问题.其实这个解决问题的思路就是算法中常用的divide and conquer, 这篇 ...
- UVA - 10375 Choose and divide[唯一分解定理]
UVA - 10375 Choose and divide Choose and divide Time Limit: 1000MS Memory Limit: 65536K Total Subm ...
- [leetcode] 29. divide two integers
这道题目一直不会做,因为要考虑的corner case 太多. 1. divisor equals 0. 2. dividend equals 0. 3. Is the result negative ...
- Leetcode Divide Two Integers
Divide two integers without using multiplication, division and mod operator. 不用乘.除.求余操作,返回两整数相除的结果,结 ...
- 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 ...
- 51nod1305 Pairwise Sum and Divide
题目链接:51nod 1305 Pairwise Sum and Divide 看完题我想都没想就直接暴力做了,AC后突然就反应过来了... Floor( (a+b)/(a*b) )=Floor( ( ...
随机推荐
- Android内存优化(三)详解内存分析工具MAT
前言 在这个系列的前四篇文章中,我分别介绍了DVM.ART.内存泄漏和内存检测工具的相关知识点,这一篇我们通过一个小例子,来学习如何使用内存分析工具MAT. 1.概述 在进行内存分析时,我们可以使用M ...
- Spring MVC 静态资源处理 (三)
完整的项目案例: springmvc.zip 目录 实例 项目结构: 一.配置web.xml <?xml version="1.0" encoding="UTF-8 ...
- python第一百三十天 ---简单的BBS论坛
简单的BBS论坛 实现功能 git仓库地址:https://github.com/uge3/BBS 1.整体参考“抽屉新热榜” + “博客园” 2.实现不同论坛版块 3.帖子列表展示 4.个人博客主页 ...
- mysql replace into 的使用情况
replace into的存在的几种情况 当表存在主键并且存在唯一键的时候 如果只是主键冲突 mysql> select * from auto; +----+---+------+------ ...
- UnicodeEncodeError: 'ascii' codec can't encode characters in position
UnicodeEncodeError: 'ascii' codec can't encode characters in position python运行时出现这个错误,解决方法如下: 加入如下语句 ...
- Centos7安装搭建FTP服务器(最简便方法)
简介: vsftpd 是“very secure FTP daemon”的缩写,安全性是它的一个最大的特点. vsftpd 是一个 UNIX 类操作系统上运行的服务器的名字,它可以运行在诸如 Linu ...
- PATH_SEPARATOR
PATH_SEPARATOR是一个常量,在Linux系统中是一个" : "号,Windows上是一个";"号.所以编写程序时最好用常量 PATH_SEPARAT ...
- windows下安装consul
Consul 是一个支持多数据中心分布式高可用的服务发现和配置共享的服务软件, 由 HashiCorp 公司用 Go 语言开发, 基于 Mozilla Public License 2.0 的协议进行 ...
- [福大软工] Z班 团队Alpha阶段成绩汇总
团队成绩汇总表 团队 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 总分 Dipper 9 85 90 26 42 27.5 120 74 25 111 19 628.5 SW ...
- 《Java大学教程》—第12章 案例研究--第2部分
本章就是上一章的延续,主要是用GUI实现了控制界面. 编程练习:代码附件Hostel.java1. 正确运行2. Runhostel.java3. searchButton