zoj 1453

/**
 * zoj 1453
 * 不需四舍五入
 *
 */
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;

struct Point {
	int x, y;
};
const double eps = 1e-5;
Point tree[110];
Point stack[110];
bool bRemain[110];
int sp;
int n;

inline int PositiveCrossProduct( Point const& p0, Point const& p1, Point const& p2 )
{
	double crsPro = ( p1.x-p0.x )*( p2.y-p0.y ) - ( p2.x-p0.x )*( p1.y-p0.y );
	if ( fabs(crsPro) < eps )
		return 0;
	else if ( crsPro > 0 )
		return 1;
	return -1;
}
bool cmp( Point const& p1, Point const& p2 )
{
	int flag =  PositiveCrossProduct( tree[0], p1, p2 );
	if ( flag > 0 || ( flag == 0 && p2.x > p1.x ) )
		return true;
	return false;
}
inline void hpSwap( int& a, int& b )
{
	a = a^b;
	b = a^b;
	a = a^b;
}
inline double segLength( Point const& p1, Point const& p2 )
{
	return sqrt( ( p1.x-p2.x )*( p1.x-p2.x ) + ( p1.y-p2.y)*( p1.y-p2.y ) );
}

int main()
{
	int i, k;
	double length;
	while ( scanf("%d", &n) != EOF ) 
	{
		if ( 0 == n )
			break;
		for ( i = 0; i < n; ++ i )
			scanf("%d%d", &tree[i].x, &tree[i].y );
		
		length=0.0;
		if ( 2 == n )
		{
			length = segLength( tree[0], tree[1] ) * 2;
			printf("%.2lf\n", length );
			continue;
		}
		else if ( 1 == n )
		{
			printf("0.00\n");
			continue;
		}
		
		//leftmost point
		k = 0;
		for ( i = 1; i < n; ++ i )
		{
			if ( tree[i].x < tree[k].x 
				//|| ( tree[i].x == tree[k].x && tree[i].y < tree[k].y ) 
				)
				k = i;
		}
		if ( k > 0 ) {
			hpSwap( tree[0].x, tree[k].x );
			hpSwap( tree[0].y, tree[k].y );
		}
	
		//sort
		sort( tree+1, tree+n, cmp );	
		
		//remove the same angle point
		memset( bRemain, 0, sizeof(bool)*n );
		for ( i = 2; i < n; ++ i )
		{
			if ( PositiveCrossProduct( tree[0], tree[i-1], tree[i] ) != 0 )
				bRemain[i-1] = true;
		}
		bRemain[n-1] = true;
		
		stack[0] = tree[0];
		stack[1] = tree[1];
		stack[2] = tree[2];
		sp = 3;
		for ( i = 3; i < n; ++ i )
		if ( bRemain[i] )
		{
			while ( PositiveCrossProduct( stack[sp-2], stack[sp-1], tree[i] ) <= 0 )
				--sp;
			stack[sp++] = tree[i];
		}
		
		//stack[] sp
		length=0.0;
		for ( i = 1; i < sp; ++ i )
			length += segLength( stack[i-1], stack[i] );
		length += segLength( stack[0], stack[sp-1] );
		printf("%.2lf\n", length );
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值