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; }
相关文章推荐
- M2M过程实例:人类解决凸包问题(从另一个角度去理解M2M模型)
- POJ 1696 Space Ant 类似凸包问题(叉积的应用)
- 凸包2:分治法解决凸包问题
- 凸包问题
- nyoj 78 圈水池 凸包问题 篱笆问题
- 凸包问题——圈水池
- Graham's Scan法求解凸包问题
- 凸包问题
- 凸包问题 nyoj 266 wall
- 【整理自用】凸包问题
- 凸包问题的五种解法
- poj 1113 凸包问题
- poj1113 Wall 凸包问题 官方数据
- 《Algorithms算法》笔记:元素排序(4)——凸包问题
- HDU 1348 Wall(基础凸包问题)
- 杭电1392——凸包问题
- NYOJ 78 圈水池(凸包问题)
- 凸包问题——圈水池
- 凸包问题的快包算法代码(C语言)
- POJ1228(稳定凸包问题)