您的位置:首页 > 其它

TOJ 1255

2014-03-12 20:49 423 查看
题目标题:

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数学题