首页 技术 正文
技术 2022年11月14日
0 收藏 404 点赞 3,242 浏览 2454 个字

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

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

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

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

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

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

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

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

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;
}
上一篇: 安装NVIDIA
下一篇: io编程,bio,nio,aio
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,492
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,907
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,740
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,495
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,132
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,295