模板题目在这里
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;
}