题目标题:
Surround the Tree
题目连接:
http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1255
题目类型:
计算几何 - 凸包
数据结构:
struct LMIC_PNT
{
int x, y;
bool operator < ( const LMIC_PNT & K ) const
{
return y < K.y || y == K.y && x < K.x;
}
} ;
思路分析:
这里单纯的采用 jarvis 的步进法
这里值得注意的是
题目中所求的是凸包的最外围的长度
而不是现实中所理解的要把外面的点"围"起来
所以2个点的话
应该是两个点的距离 而不是一个来回
证明:
略
源代码:
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
#define MAXN 1005
#define PI acos( -1 )
struct LMIC_PNT
{
int x, y;
bool operator < ( const LMIC_PNT & K ) const
{
return y < K.y || y == K.y && x < K.x;
}
} ;
int n, cnt, tail, arr[MAXN], sta[MAXN];
LMIC_PNT pnt[MAXN];
bool _crolft( LMIC_PNT p1, LMIC_PNT p2, LMIC_PNT p3 )
{
return ( ( p3.x - p1.x ) * ( p2.y - p1.y ) - ( p2.x - p1.x ) * ( p3.y - p1.y ) ) < 0;
}
void _jarvis()
{
int i;
tail = cnt = 0;
sort( pnt, pnt + n );
sta[tail ++] = 0;
sta[tail ++] = 1;
for( i = 2; i < n; i ++ )
{
while( tail > 1 && !_crolft( pnt[sta[tail - 1]], pnt[sta[tail - 2]], pnt[i] ) )
{
tail --;
}
sta[tail ++] = i;
}
for( i = 0; i < tail; i ++ )
{
arr[cnt ++] = sta[i];
}
tail = 0;
sta[tail ++] = n - 1;
sta[tail ++] = n - 2;
for( i = n - 3; i >= 0; i -- )
{
while( tail > 1 && !_crolft( pnt[sta[tail - 1]], pnt[sta[tail - 2]], pnt[i] ) )
{
tail --;
}
sta[tail ++] = i;
}
for( i = 0; i < tail; i ++ )
{
arr[cnt ++] = sta[i];
}
}
int main()
{
int i, c = 1;
while( scanf( "%d", &n ), n )
{
for( i = 0; i < n; i ++ )
{
scanf( "%d%d", &pnt[i].x, &pnt[i].y );
}
if( n == 1 )
{
printf( "0.00\n" );
continue;
}
_jarvis();
double r = 0.0;
for( i = 0; i < cnt - 1; i ++ )
{
int tmp_x = ( pnt[arr[i]].x - pnt[arr[i + 1]].x ),
tmp_y = ( pnt[arr[i]].y - pnt[arr[i + 1]].y );
r += sqrt( tmp_x * tmp_x + tmp_y * tmp_y * 1.0 );
}
if( n == 2 )
{
printf( "%.2lf\n", r / 2 );
}
else
{
printf( "%.2lf\n", r );
}
}
return 0;
}