Graham's Scan法求解凸包问题:http://www.cnblogs.com/devymex/archive/2010/08/09/1795392.html
/*
zoj_1453 计算几何-凸包
凸包第一题。计算几何方面自己几乎是一片空白,要好好加强了~
自己按照网上讲的Graham()算法写的一个模板,要多多改善才是。
*/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
struct node
{
double x,y,tan;
};
node tree[110];
bool cmp( node a,node b )
{
return a.tan<b.tan;
}
double count( int a,int b )
{
return sqrt( (tree[a].y-tree[b].y)*(tree[a].y-tree[b].y)+
(tree[a].x-tree[b].x)*(tree[a].x-tree[b].x) );
}
double Graham( node sta,int n )
{
int s[110];
int i,top;
double sum;
node a,b;
s[0]=0; s[1]=1; s[2]=2;
top=2;
for( i=3;i<n;i++ )
{
while( 1 )
{
a.x=tree[ s[top] ].x-tree[ s[top-1] ].x;
a.y=tree[ s[top] ].y-tree[ s[top-1] ].y;
b.x=tree[i].x-tree[ s[top] ].x;
b.y=tree[i].y-tree[ s[top] ].y;
if( a.x*b.y-a.y*b.x<0 )
{
top--;
continue;
}
break;
}
s[ ++top ]=i;
}
sum=0;
for( i=1;i<=top;i++ )
sum+=count( s[i],s[i-1] );
sum+=count( s[0],s[top] );
return sum;
}
int main()
{
int n,i;
node sta;
double sum;
while( scanf( "%d",&n ) && n )
{
sta.x=sta.y=10000000;
for( i=0;i<n;i++ )
{
scanf( "%lf%lf",&tree[i].x,&tree[i].y );
if( sta.y>tree[i].y || ( sta.y==tree[i].y && sta.x<tree[i].x ) )
sta=tree[i]; //记录y值最小点
}
if( n==1 ) printf( "0.00\n" );
else if( n==2 ) printf( "%.2lf\n",2*count(0,1) );
else
{
for( i=0;i<n;i++ )
tree[i].tan=atan2( tree[i].y-sta.y , tree[i].x-sta.x );
sort( tree,tree+n,cmp );
printf( "%.2lf\n",Graham( sta,n ) );
}
}
return 0;
}