【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;
}

发布了159 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/KIKO_caoyue/article/details/99721645
今日推荐