凸包裸题。。。之前我从来没涉及过计算几何,现在觉得还是要学一学,至少可以写个暴力23333
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
#define N 5010
#define epx 1e-8
const double pi=atan(1.0)*4;
int n,m,top;
double Ans;
struct Point{
double x,y;
Point operator + (const Point &a) const{
return (Point){x+a.x,y+a.y};
}
Point operator - (const Point &a) const{
return (Point){x-a.x,y-a.y};
}
double operator * (const Point &a) const{
return x*a.y-y*a.x;
}
bool operator == (const Point &a) const{
return fabs(x-a.x)<epx&&fabs(y-a.y)<epx;
}
bool operator != (const Point &a) const{
return !((Point){x,y}==a);
}
}p[N],S[N];
double sqr(double x){return x*x;};
bool Cmp(const Point &a,const Point &b)
{
if(fabs((b-p[1])*(a-p[1]))<epx)
return a.y<b.y;
else return (a-p[1])*(b-p[1])>0;
}
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void Graham()
{
int t=1;
for(int i=2;i<=n;i++)
if(p[i].y<p[t].y||(p[i].y==p[t].y&&p[i].x<p[t].x))
t=i;
swap(p[1],p[t]);
sort(p+2,p+n+1,Cmp);
S[++top]=p[1];S[++top]=p[2];
for(int i=3;i<=n;i++)
{
while((S[top]-S[top-1])*(p[i]-S[top-1])<=epx&&top>1)
top--;
S[++top]=p[i];
}
S[top+1]=p[1];
for(int i=1;i<=top;i++)
Ans+=sqrt(sqr(S[i].x-S[i+1].x)+sqr(S[i].y-S[i+1].y));
}
int main()
{
n=read();
for(int i=1;i<=n;i++)
p[i].x=read(),p[i].y=read();
Graham();
printf("%.2lf\n",Ans);
return 0;
}