裸的凸包,直接造一个凸包,然后算一下长度就好了
c++代码如下:
#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i =x ;i <= y; ++ i)
#define repd(i,x,y) for(register int i = x; i >= y ; -- i)
using namespace std;
typedef long long ll;
template<typename T>inline void read(T&x)
{
x = 0;char c;int sign = 1;
do { c = getchar(); if(c == '-') sign = -1; }while(!isdigit(c));
do { x = x * 10 + c - '0'; c = getchar(); }while(isdigit(c));
x *= sign;
}
const int N = 5e3 + 500;
int n,q[N],top;
struct Point
{
int x,y;
bool operator < (const Point Q) const { return x < Q.x || x == Q.x && y < Q.y; }
Point operator - (const Point Q) const { return (Point){x - Q.x,y - Q.y}; }
}p[N];
ll cross(Point x,Point y)
{
return (ll)x.x * y.y - (ll)y.x * x.y;
}
int main()
{
read(n);
rep(i,1,n)
read(p[i].x),read(p[i].y);
sort(p + 1, p + 1 + n);
rep(i,1,n)
{
while(top > 1 && cross(p[q[top]] - p[q[top - 1]] , p[i] - p[q[top]]) < 0) top--;
q[++top] = i;
}
int cnt = top;
repd(i,n,1)
{
while(top > cnt && cross(p[q[top]] - p[q[top - 1]] ,p[i] - p[q[top]]) < 0) top--;
q[++top] = i;
}
double ans = 0;
rep(i,2,top)
ans += sqrt((p[q[i]].x - p[q[i - 1]].x) * (p[q[i]].x - p[q[i - 1]].x) + (p[q[i]].y - p[q[i - 1]].y)*(p[q[i]].y - p[q[i - 1]].y));
printf("%.2lf\n",ans);
return 0;
}