#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<iomanip>
using namespace std;
struct node
{
double i, j;
bool operator <(const node &a)
{
if(i != a.i)
return i < a.i;
return j < a.j;
}
};
double cross(node a, node b, node c)//判断新加方向
{
return (a.i - c.i) * (b.j - c.j) - (a.j - c.j) * (b.i - c.i);
}
double dis(node a, node b)
{
return sqrt((a.i - b.i) * (a.i - b.i) + (a.j - b.j) * (a.j - b.j));
}
node a[1010];
node res[1010];
void acc_ios()
{
ios::sync_with_stdio(false);
cin.tie(0);
}
int main()
{
acc_ios();
int n;
while(cin>>n)
{
if(n == 0)
break;
for(int i = 0; i < n; i++)
cin>>a[i].i>>a[i].j;
if(n == 1)
{
cout<<"0.00"<<endl;
}
else if(n == 2)
{
cout<<fixed<<setprecision(2)<<dis(a[0], a[1])<<endl;
}
else
{
sort(a, a + n);
int tot = 2;
res[0] = a[0], res[1] = a[1];
for(int i = 2; i < n; i++)//求下凸包
{
while(tot >= 2 && cross(a[i], res[tot - 1], res[tot - 2]) > 0)
tot--;
res[tot++] = a[i];
}
int p = tot;
for(int i = n - 2; i >= 0; i--)//求上凸包
{
while(tot >= p && cross(res[tot - 1], a[i], res[tot - 2]) < 0)
tot--;
res[tot++] = a[i];
}
double ans = 0;
tot--;
for(int i = 0; i < tot; i++)
ans += dis(res[i], res[i + 1]);
cout<<fixed<<setprecision(2)<<ans<<endl;
}
}
return 0;
}
凸包模板
最新推荐文章于 2023-12-02 16:55:27 发布