zoj 3234

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;

struct Point {
	int x, y;
};
const int N = 2010;
Point soldier[N];
int n, cnt;

int pt[N];
bool flag[N];
int pcnt;

bool bRemain[N];

int stack[N];
int sp;

inline int PositiveCrossProduct( Point const& p0, Point const& p1, Point const& p2 )
{
	/**
	 *  要不然WA
	 */
	long long a = ( p1.x-p0.x );
	long long b = ( p2.y-p0.y );
	long long c = ( p2.x-p0.x );
	long long d = ( p1.y-p0.y );
	long long crsPro = a*b - c*d;
	if ( 0 == crsPro )
		return 0;
	else if ( crsPro > 0 )
		return 1;
	return -1;
}
inline void hpSwap( int& a, int& b )
{
	a = a^b;
	b = a^b;
	a = a^b;
}
bool cmp( int const& p1, int const& p2 )
{
	int flag =  PositiveCrossProduct( soldier[ pt[0] ], soldier[p1], soldier[ p2] );
	if ( flag > 0 
			/*|| 
			( flag == 0 && ( soldier[p2].x > soldier[p1].x  || 
				( soldier[p2].x == soldier[p1].x && soldier[p2].y > soldier[p1].y ) 
			) )*/
		)
		return true;
	return false;
}
inline void RemoveCyclePoint() 
{
	int i; 
	for ( i = 0; i < sp; ++ i )
		flag[ stack[i] ] = true; 

	pcnt = 0;
	for ( i = 0; i < n; ++ i )
	{
		if ( flag[i] == false )
			pt[ pcnt++ ] = i;
	}
}
bool GrahamScan()
{
	//leftmost
	int i, k;
	k = 0;
	for ( i = 1; i < pcnt; ++ i )
	{
		if ( soldier[ pt[i] ].x < soldier[ pt[k] ].x 
				|| ( soldier[ pt[i] ].x == soldier[ pt[k] ].x 
				&& soldier[ pt[i] ].y < soldier[ pt[k] ].y ) )
			k = i;
	}
	if ( k > 0 )
		hpSwap( pt[0], pt[k] );
	
	sort( pt+1, pt+pcnt, cmp );

	memset( bRemain, 0, sizeof(bool)*pcnt );
	for ( i = 2; i < pcnt; ++ i )
	{
		if ( PositiveCrossProduct( soldier[ pt[0] ], soldier[ pt[i-1] ], soldier[ pt[i] ] ) != 0 )
			bRemain[i-1] = true;
	}
	bRemain[pcnt-1] = true;
	
	/*
	stack[0] = pt[0];
	i = 1;
	while ( i < pcnt && bRemain[i] == false ) ++ i;
	if ( i >= pcnt )
		return false;
	stack[1] = pt[i++];
	while ( i < pcnt && bRemain[i] == false ) ++ i;
	if ( i >= pcnt )
		return false;
	stack[2] = pt[i];
	sp = 3;
	*/
	stack[0] = pt[0];
	stack[1] = pt[1];
	stack[2] = pt[2];
	sp = 3;
	for ( i = 3; i < pcnt; ++ i )
	if ( bRemain[i] )
	{
		while ( PositiveCrossProduct( soldier[ stack[sp-2]], soldier[ stack[sp-1]], soldier[ pt[i] ] ) < 0 )
			-- sp;
		stack[sp++] = pt[i];
	}

	RemoveCyclePoint();
	return true;
}

int main()
{
	int i;
	while ( scanf("%d", &n ) != EOF )
	{
		for ( i = 0; i < n; ++ i )
		{
			scanf("%d%d", &soldier[i].x, &soldier[i].y );
			pt[i] = i;
		}
		pcnt = n;

		cnt = 0;
		memset( flag, 0, sizeof(flag) );
		while ( pcnt > 2 )
		{
			++ cnt;
			if ( GrahamScan() == false )
				break;
		}
		printf("%d\n", cnt);
	}
	
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章