首页 > 其他分享 >二维凸包

二维凸包

时间:2022-08-16 23:15:22浏览次数:50  
标签:double top Pos 凸包 二维 define

二维凸包模板

其实二维凸包是个很简单的东西
想象一下我们在二维平面上打了很多柱子,凸包其实就是往上面套橡皮筋,收到最紧就是了

我们把这些桩子按照x,y从小到大排序
发现什么呢?数组内第一个和最后一个点一定在凸包上
为什么呢?我们来思考一下第一个桩子
如果它不在橡皮筋上,那它左边肯定得有人帮他撑着呢
但是?没有啊!
末尾的柱子同理,右边没有柱子给他撑着

那我们咋找凸包呢?
我们把凸包用左右两个端点分成两个部分,向上凸叫上凸包,下凸包同理
如何找下凸包?
想象一下下凸包的形状,不难发现这些线段的斜率都是不断上升的
于是我们把每个点入栈,如果发现加入这个点,和之前的点构成的斜率不是递增的,就把上一个点扔了
为什么不把当前点扔了呢?扔了前面的点,目前点可以包含之前的,反之不可以

上凸包对称操作即可

代码:

// Problem: P2742 [USACO5.1]圈奶牛Fencing the Cows /【模板】二维凸包
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2742
// Memory Limit: 128 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#include <bits/extc++.h>
#define INF 0x7fffffff
#define MAXN 100005
#define MAXM 10003
#define eps 1e-9
#define foru(a,b,c)	for(int a=b;a<=c;a++)
#define ford(a,b,c)	for(int a=b;a>=c;a--)
#define RT return 0;
#define db(x)	cout<<endl<<x<<endl;
#define LL long long
#define LXF int
#define RIN rin()
#define HH printf("\n")
using namespace std;
inline LXF rin(){
	LXF x=0,w=1;
	char ch=0;
	while(ch<'0'||ch>'9'){ 
	if(ch=='-') w=-1;
	ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
	x=x*10+(ch-'0');
	ch=getchar();
	}
	return x*w;
}
inline void out(LXF x){
	if(x<0){
	x=-x;
	putchar('-');
	}
	if(x>9) out(x/10);
	putchar(x%10+'0');
}
struct Pos{
	double x,y;
}a[MAXN],s[MAXN];
int n;
double ans;
int top=0;
double dis(Pos p,Pos q){
	return sqrt((q.x-p.x)*(q.x-p.x)+(q.y-p.y)*(q.y-p.y));
}
double getk(Pos p,Pos q){
	return (q.y-p.y)/(q.x-p.x);
}
bool cmp(Pos p,Pos q){
	return p.x!=q.x?p.x<q.x:p.y<q.y;
}
int main(){
	scanf(" %d",&n);
	for(int i=1;i<=n;i++){
		scanf(" %lf %lf",&a[i].x,&a[i].y);
	}
	sort(a+1,a+1+n,cmp);
	for(int i=1;i<=n;i++){
		s[++top]=a[i];
		while(top>=3&&getk(s[top-1],s[top])<getk(s[top-2],s[top-1])){
			top-=2;
			s[++top]=a[i];
		}
	}
	for(int i=2;i<=top;i++){
		ans+=dis(s[i-1],s[i]);
	}
	top=0;
	for(int i=1;i<=n;i++){
		s[++top]=a[i];
		while(top>=3&&getk(s[top-1],s[top])>getk(s[top-2],s[top-1])){
			top-=2;
			s[++top]=a[i];
		}
	}
	for(int i=2;i<=top;i++){
		ans+=dis(s[i-1],s[i]);
	}
	printf("%.2lf",ans);
	return 0;
}

标签:double,top,Pos,凸包,二维,define
From: https://www.cnblogs.com/XHZS-XY/p/16593330.html

相关文章

  • opencv4.x 中的plot函数绘制二维Mat
     发现一个好玩的二维图像绘制函数,与大家共同欣赏:)参考网址:OpenCV4入门061:使用plot2d绘制折线图-食铁兽(feater.top) 头文件:#include<opencv2/plot.hpp>动态库:-l......
  • 2022 杭电多校第八场 Vale of Eternal 凸包+找规律
    主要是存个代码,还有我踩的坑。。cin和cout真的很慢,很慢,非常慢..还有就是先把凸包求出来了,然后才能考虑凸包面积啥的刚开始思路错了,直接上多边形面积明明输出和标程都一......
  • [ 模板 ] 求凸包面积
    先求凸constintN=1e6;structPoint{doublex,y;doubleoperator^(constPoint&b)const{returnx*b.y-y*b.x;}};Pointstackk[N];......