【Graham Scan 求凸包】洛谷P2742 模板

模板题目在这里
Attention
本文不会讲解任何Graham Scan算法的思路和过程。

p[i]表示第i个点。
H[i]表示凸包上第i个点。
tot表示凸包上最后一个点的标号。
注:tot从0开始。
cp是向量叉积
dist是两点之间欧几里得距离

#include <bits/stdc++.h>
#define sc(n) scanf("%d",&n)
#define pt(n) printf("%d\n",n)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define vi vector<int>
#define vl vector<long long>
#define pb push_back
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e5+7;
struct node
{
	double x,y;
}p[maxn],H[maxn];
double cp(node A,node B,node C)
{
	return (B.x-A.x)*(C.y-A.y)-(C.x-A.x)*(B.y-A.y);
}
double dist(node A,node B)
{
	return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}
bool cmp(node A,node B)
{
	double pp = cp(p[0],A,B);
	if(pp>0) return true;
	if(pp<0) return false;
	return dist(p[0],A)<dist(p[0],B);
} 
int n,tot;
int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
	for(int i=0;i<n;i++)
	{
		if(p[i].y<p[0].y) swap(p[0],p[i]);
		else if(p[i].y==p[0].y && p[i].x<p[0].x) swap(p[i],p[0]);
	}
	sort(p+1,p+n,cmp);
	H[0] = p[0];
	H[1] = p[1];
	tot = 1;
	for(int i=2;i<n;i++)
	{
		while(tot>0 && cp(H[tot-1],H[tot],p[i])<=0) tot--;
		tot++;
		H[tot] = p[i];
	}
	double ans = 0;
	for(int i=0;i<tot;i++) ans += dist(H[i],H[i+1]);
	ans += dist(H[0],H[tot]);
	printf("%.2lf\n",ans);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值