#include<iostream>
#include<cmath>
using namespace std;
struct Point
{
double x, y;
};
const int MAXN=105;
Point p[MAXN]; //存放所有的点
Point result[MAXN]; //存放凸包上的点
int top;
double xmult(Point a, Point b, Point c)
{
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
double dist(Point a, Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int cmp(const void *a, const void *b) //以左下角的点为基点,其它点与该点的连线与x轴所成的角度,从小到大排序
{
Point p1=*(Point*)a;
Point p2=*(Point*)b;
double x=xmult(p[0], p1, p2);
if (x<0) return 1;
if (x==0 && dist(p[0], p1)<dist(p[0], p2)) return 1;
return -1;
}
void create_convex(int n) //生成凸包
{
result[0]=p[0];
result[1]=p[1];
result[2]=p[2];
int i;
top=2;
for (i=3; i<=n; i++)
{
while (xmult(result[top-1], result[top], p[i])<=0 && top>=1) top--;
result[++top]=p[i];
}
}
int main()
{
int n;
while (cin>>n, n)
{
int i;
for (i=0; i<n; i++)
{
cin>>p[i].x>>p[i].y;
}
if (n==1)
{
puts("0.00");
continue;
}
if (n==2)
{
double len=dist(p[0], p[1]);
printf("%.2lf\n", len);
continue;
}
Point tmp;
int pos=0;
tmp.x=p[0].x; tmp.y=p[0].y;
for (i=1; i<n; i++) //寻找左下角的点
{
if (p[i].y<tmp.y)
{
tmp.x=p[i].x;
tmp.y=p[i].y;
pos=i;
}
if (p[i].y==tmp.y && p[i].x<tmp.x)
{
tmp.x=p[i].x;
tmp.y=p[i].y;
pos=i;
}
}
swap(p[0], p[pos]);
/* tmp=p[0];
p[0]=p[pos];
p[pos]=tmp;*/
qsort(&p[1], n-1, sizeof(p[0]), cmp);
p[n]=p[0];
create_convex(n);
double len=0.0;
for (i=1; i<=top; i++)
{
len+=dist(result[i-1], result[i]);
}
printf("%.2lf\n", len);
}
return 0;
}
#include<cmath>
using namespace std;
struct Point
{
double x, y;
};
const int MAXN=105;
Point p[MAXN]; //存放所有的点
Point result[MAXN]; //存放凸包上的点
int top;
double xmult(Point a, Point b, Point c)
{
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
double dist(Point a, Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int cmp(const void *a, const void *b) //以左下角的点为基点,其它点与该点的连线与x轴所成的角度,从小到大排序
{
Point p1=*(Point*)a;
Point p2=*(Point*)b;
double x=xmult(p[0], p1, p2);
if (x<0) return 1;
if (x==0 && dist(p[0], p1)<dist(p[0], p2)) return 1;
return -1;
}
void create_convex(int n) //生成凸包
{
result[0]=p[0];
result[1]=p[1];
result[2]=p[2];
int i;
top=2;
for (i=3; i<=n; i++)
{
while (xmult(result[top-1], result[top], p[i])<=0 && top>=1) top--;
result[++top]=p[i];
}
}
int main()
{
int n;
while (cin>>n, n)
{
int i;
for (i=0; i<n; i++)
{
cin>>p[i].x>>p[i].y;
}
if (n==1)
{
puts("0.00");
continue;
}
if (n==2)
{
double len=dist(p[0], p[1]);
printf("%.2lf\n", len);
continue;
}
Point tmp;
int pos=0;
tmp.x=p[0].x; tmp.y=p[0].y;
for (i=1; i<n; i++) //寻找左下角的点
{
if (p[i].y<tmp.y)
{
tmp.x=p[i].x;
tmp.y=p[i].y;
pos=i;
}
if (p[i].y==tmp.y && p[i].x<tmp.x)
{
tmp.x=p[i].x;
tmp.y=p[i].y;
pos=i;
}
}
swap(p[0], p[pos]);
/* tmp=p[0];
p[0]=p[pos];
p[pos]=tmp;*/
qsort(&p[1], n-1, sizeof(p[0]), cmp);
p[n]=p[0];
create_convex(n);
double len=0.0;
for (i=1; i<=top; i++)
{
len+=dist(result[i-1], result[i]);
}
printf("%.2lf\n", len);
}
return 0;
}