您的位置:首页 > 其它

Codeforces166B 凸包问题

2019-07-31 21:28 35 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq_40534166/article/details/97962983

CF166B 凸包问题(模板)

题目链接:http://codeforces.com/problemset/problem/166/B

题意:给出两个多边形A的n个点a1、a2…an,多边形B的m个点b1、b2…bm,保证A是一个凸多边形,判断B是否完全包含在A内。

首先,凸包的定义如下:
给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边形,它能包含点集中所有的点。
eg:

解题思路:
可以运用安德鲁法先求出多边形A的凸包,并得到凸包的点集合res及点的个数m1;再将多边形A和B的所有点放在一起,求出所有点a1、a2…an、b1、b2…bm的凸包,得到此凸包的点集合res2以及点的个数m2。之后比较m1、m2以及两个点集数组res、res2即可。

如果B在A内,把B的点放入A的点中后对其凸包没有影响
-----➤m1、m2以及res、res2如果相同则B在A内,否则B不在A内

注意:cin会TLE,要改为scanf,切记!

AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<cstdlib>
//#include<bits/stdc++.h>
using namespace std;
#define scan(n) scanf("%d",&n)
#define scand(n) scanf("%lf",&n)
#define ll long long
#define eps 1e-8

struct point
{
double x,y;
point() {} point(double _x,double _y)
{
x=_x;
y=_y;
}
point operator - (const point &b) const
{
return point(x-b.x,y-b.y);
}
bool operator < (const point &b) const
{
return x<b.x||x==b.x&&y<b.y;
}
}res[120005],pa[120005],pb[120005],res2[120005];
//res:得到的凸包的点
//p:原点数组

typedef point Vector;//向量

int dcmp(double x)
{
return (x>eps)-(x<-eps);
}

double cross(Vector a,Vector b)//求向量叉乘
{
return a.x*b.y-b.x*a.y;
}

int andrew1(struct point p[],int n)
{
sort(p,p+n);
int m=0;
for (int i=0; i<n; i++)
{
while(m>1&&cross(res[m-1]-res[m-2],p[i]-res[m-2])<0)
--m;
res[m++]=p[i];
}
int k=m;
for (int i=n-2; i>=0; --i)
{
while (m>k&&cross(res[m-1]-res[m-2],p[i]-res[m-2])<0)
--m;
res[m++]=p[i];
}
if (m>1)
--m;
return m;//m:凸包中点的个数(下标从0到m-1)
}

int andrew2(struct point p[],int n)
{
sort(p,p+n);
int m=0;
for (int i=0; i<n; i++)
{
while(m>1&&cross(res2[m-1]-res2[m-2],p[i]-res2[m-2])<0)
--m;
res2[m++]=p[i];
}
int k=m;
for (int i=n-2; i>=0; --i)
{
while (m>k&&cross(res2[m-1]-res2[m-2],p[i]-res2[m-2])<0)
--m;
res2[m++]=p[i];
}
if (m>1)
--m;
return m;//m:凸包中点的个数(下标从0到m-1)
}

int main()
{
int n,m,i,a,b;
scan(n);
for(i=0;i<n;i++)
{
scand(pa[i].x);
scand(pa[i].y);
pb[i].x=pa[i].x;
pb[i].y=pa[i].y;
}
int m1=andrew1(pa,n);
scan(m);
for(i=0;i<m;i++)
{
scand(pb[i+n].x);
scand(pb[i+n].y);
}
int m2=andrew2(pb,n+m);
if(m1!=m2)
{
printf("NO\n");
return 0;
}
sort(res,res+m1);
sort(res2,res2+m2);
int f=1;
for(i=0;i<m1;i++)
{
double x1=res[i].x,x2=res2[i].x;
double y1=res[i].y,y2=res2[i].y;
if(fabs(x1-x2)<eps&&fabs(y1-y2)<eps)
continue;
else
{
f=0;
break;
}
}
if(f==0)
printf("NO\n");
else
printf("YES\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: