191227-计算几何-凸包

本文介绍了一种计算几何中求凸包的经典算法——Graham扫描法。该算法通过预处理找到极点,然后利用角度和距离进行排序,最后通过单调栈维护扫描过程,有效地去除无用点,得到凸包的顶点。代码实现详细,包括点结构定义、运算符重载、比较函数及主函数调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

191227-计算几何-凸包

Graham扫描法

#include<bits/stdc++.h>
#define M 20009 
using namespace std;
struct point{
	double x,y;
	point(double a=0,double b=0){x=a,y=b;}
	friend inline point operator+(const point &a,const point &b){return point(a.x+b.x,a.y-b.y);}
	friend inline point operator-(const point &a,const point &b){return point(a.x-b.x,a.y-b.y);}
	friend inline double operator*(const point &a,const point &b){return a.x*b.y-a.y*b.x;}
	friend inline double operator^(const point &a,const point &b){return a.x*b.x+a.y*b.y;}
	inline double dist(){return sqrt(x*x+y*y);}
}p[M],q[M];
int last,n;
bool cmp(const point &a,const point &b){
	double res=(a-p[1])*(b-p[1]);
	if(res) return res>0;
	return (a-p[1]).dist()<(b-p[1]).dist();//如果三点过线,需要特判 
}
void graham(){
	int dat=1;
	for(int i=2;i<=n;i++)
		if(p[i].x<p[dat].x||p[i].x==p[dat].x&&p[i].y<p[dat].y)
			dat=i;//选取极点 
	swap(p[dat],p[1]);
	sort(p+2,p+1+n,cmp);
	q[++last]=p[1];//单调栈维护 
	for(int i=2;i<=n;i++){
		while(last>2&&(p[i]-q[last-1])*(q[last]-q[last-1])>=0) last--;//依次扫描并丢去无用的点 
		q[++last]=p[i];
	}
}
double calc(){
	double ans=0;
	ans+=(q[last]-q[1]).dist();
	while(last>1){
		ans+=(q[last]-q[last-1]).dist();
		last--;
	}return ans;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%lf%lf",&p[i].x,&p[i].y);
	graham();
	printf("%.2lf",calc());
	return 0;
}

例题集锦

传送门

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值