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

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

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

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

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

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

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

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

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. JMeter Dubbo请求插件jmeter-plugin-dubbo.jar

    JMeter Dubbo请求插件jmeter-plugin-dubbo.jar   by:授客 QQ:1033553122 测试环境 apache-jmeter-3.2 Dubbo  2.6.2 声明 ...

  2. Play 2D games on Pixel running Android Nougat (N7.1.2) with Daydream View VR headset

  3. springboot 学习之路 6(集成durid连接池)

    目录:[持续更新.....] spring 部分常用注解 spring boot 学习之路1(简单入门) spring boot 学习之路2(注解介绍) spring boot 学习之路3( 集成my ...

  4. [Python][小知识][NO.1] Python字符串前 加 u、r、b 的含义

    1.字符串前加 u 例:u"我是含有中文字符组成的字符串." 作用:后面字符串以 Unicode 格式 进行编码,一般用在中文字符串前面,防止因为源码储存格式问题,导致再次使用时出 ...

  5. springmvc复习笔记----Restful 风格,PathVariable获取 Url实例

    结构 包与之前相同 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi=&qu ...

  6. Android音频系统

    1 分析思路 Thread如何创建? AudioPolicyService是策略的制定者,AudioFlinger是策略的执行者, 所以: AudioPolicyService根据配置文件使唤Audi ...

  7. shell的while和until 的用法

    shell while循环工作中使用的不多,一般适用于守护进程程序或始终循环执行场景,其他循环计算等. while条件句: 语法: while 条件 do 指令… done ok,我们测试一下: 测试 ...

  8. ASP.NET -- WebForm -- 缓存Cache的使用

    ASP.NET -- WebForm --  缓存Cache的使用 把数据从数据库或文件中读取出来,放在内存中,后面的用户直接从内存中取数据,速度快.适用于经常被查询.但不经常变动的数据. 1. Te ...

  9. PTA天梯 L3-007 天梯地图

    L3-007 天梯地图 题目: 本题要求你实现一个天梯赛专属在线地图,队员输入自己学校所在地和赛场地点后,该地图应该推荐两条路线:一条是最快到达路线:一条是最短距离的路线.题目保证对任意的查询请求,地 ...

  10. Spring的AOP基于AspectJ的注解方式开发3

    上上偏博客介绍了@Aspect,@Before 上篇博客介绍了spring的AOP开发的注解通知类型:@Before,@AfterThrowing,@After,@AfterReturning,@Ar ...