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( ( ...
随机推荐
- HashMap 与 ConcrrentHashMap 使用以及源码原理分析
前奏一:HashMap面试中常见问题汇总 HashMap的工作原理是近年来常见的Java面试题,几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道HashTable和Has ...
- Python高级特性:列表生成式
列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式. 最常见的例子: 生成list [, , , , , , , , , ]可以用li ...
- springboot 学习之路 7(静态页面自动生效问题)
目录:[持续更新.....] spring 部分常用注解 spring boot 学习之路1(简单入门) spring boot 学习之路2(注解介绍) spring boot 学习之路3( 集成my ...
- (网页)HTML5 Canvas ( 事件交互, 点击事件为例 ) isPointInPath(转)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- codeforces 803D Magazine Ad(二分+贪心)
Magazine Ad 题目链接:http://codeforces.com/contest/803/problem/D ——每天在线,欢迎留言谈论. 题目大意: 给你一个数字k,和一行字符 例: g ...
- tkinter——GUI设计实操
1.创建root: from tkinter import * root = Tk() root.title('GUI设计') # root.attributes("-alpha" ...
- ERP按序打印问题
按序打印只适合一个机器,不适合主副机模式,主副机模式请勾选同时打印 如果开启主副机模式勾选了按序打印,会造成副机下厨后厨不出单
- Hive分区
注意:必须在表定义时指定对应的partition字段. 一.指定分区 1.单分区 建表语句:create table day_table(id int, content string) partiti ...
- 记一次zookeeper单机伪集群分布
zookeeper的各版本(历史版本)下载地址:http://apache.org/dist/zookeeper/ 环境>:linux 下载的zookeeper解压成3个
- Django创建新项目
1.安装Django 终端中输入:pip install Django==2.1.4 等于号后面的为版本,选则适合自己python的版本,如下图 Django version Py ...