http://acm.hdu.edu.cn/showproblem.php?pid=1392
type point=record
x,y:longint;
end;
var s,p:array[1..200]of point;
n,l,i,min,i1,x1,tot:longint;
x,y:array[1..200]of longint;
p0:point;
ans:real;
{
operator -(a,b:point)c:point;
begin
c.x:=a.x-b.x;
c.y:=a.y-b.y;
end;
operator *(a,b:point)c:longint;
begin
c:=a.x*b.y-a.y*b.x;
end;
}
function f(a,b,c:point):longint;
var u1,u2,v1,v2:longint;
begin
u1:=a.x-c.x;
v1:=a.y-c.y;
u2:=b.x-c.x;
v2:=b.y-c.y;
f:=u1*v2-u2*v1;
end;
procedure qsort(l,r:longint;p0:point);
var i,j:longint;
mid,t:point;
begin
i:=l;j:=r;
mid:=p[(l+r) div 2];
repeat
while f(p[i],mid,p0)>0 do i:=i+1;
while f(p[j],mid,p0)<0 do j:=j-1;
if i<=j then
begin
t:=p[i];p[i]:=p[j];p[j]:=t;
i:=i+1;j:=j-1;
end;
until i>j;
if i<r then qsort(i,r,p0);
if l<j then qsort(l,j,p0);
end;
begin
read(n);
while n<>0 do
begin
min:=maxlongint;x1:=0;i1:=0;
for i:=1 to n do
begin
read(x[i],y[i]);
if (min=y[i])and(x1>x[i]) then begin x1:=x[i];i1:=i;end;
if min>y[i] then begin min:=y[i];x1:=x[i];i1:=i;end;
end;
p0.x:=x1;p0.y:=min;
l:=0;
for i:=1 to n do
if i<>i1 then
begin
l:=l+1;
p[l].x:=x[i];
p[l].y:=y[i];
end;
qsort(1,n-1,p0);
fillchar(s,sizeof(s),0);
tot:=1;
s[1]:=p0;
for i:=1 to n-1 do
begin
while (tot>=2)and(f(s[tot-1],p[i],s[tot])>0) do tot:=tot-1;
tot:=tot+1;
s[tot]:=p[i];
end;
ans:=0;
for i:=1 to tot-1 do
ans:=ans+sqrt(sqr(s[i].x-s[i+1].x)+sqr(s[i].y-s[i+1].y));
if tot>2 then ans:=ans+sqrt(sqr(s[tot].x-s[1].x)+sqr(s[tot].y-s[1].y));
writeln(ans:0:2);
read(n);
end;
end.