Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

Re:做题总结以及注意事项

Posted by ixor at 2011-03-24 21:04:20 on Problem 1009 and last updated at 2011-03-24 21:10:51
In Reply To:做题总结以及注意事项 Posted by:ixor at 2011-03-24 21:02:50
//g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
//by ixor( linuxboy_007@hotmail.com )
//简洁起见,使用了一些stl容器,且函数分地较细,
//所以速度并没有完全发挥出来,这方面的优化做的
//不足,仅供参考。

#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <list>
#include <vector>
#include <algorithm>

using namespace std;

typedef int PixelVal;

typedef struct RLE_TAG{
	PixelVal val;
	size_t cnt;

	RLE_TAG( int val_a, int cnt_a ):val( val_a ), cnt( cnt_a ) {}
} RleElement;

typedef vector<RleElement> Row;
typedef vector<RleElement> Res;

inline void printRow( const Row &row ){
	Row::const_iterator iter;
	for( iter = row.begin(); iter != row.end(); iter ++ ){
		printf( "(%d,%d)\t", iter->val, iter->cnt  );
	}
	printf( "\n" );
}


inline bool getRow( Row &row, const int & width, Res &res ){
	typedef enum SpeedUp_Tag{
		PENDING,
		READY,
		GO
	} SpeedUp;
	static SpeedUp state = PENDING;

	static PixelVal val = -1;
	static size_t runLen = 0;
	static size_t zeroCnt = 0; 

	row.clear();

	switch( state ){
		case PENDING:
			break;

		case READY:
			state = GO;
			break;

		case GO:
			res.push_back( RleElement( 0, zeroCnt ) );
			zeroCnt = 0;
			state = PENDING;
			break;

		default:
			assert( false );
			break;
	}	

	if( !runLen ){
		fscanf( stdin, "%d %d", &val, &runLen );
		if( !val && !runLen ) 
			return false;
	}
	
	int loadLen = 0;
	int readCnt = 0;
	while( loadLen != width ){
		if( runLen >= width - loadLen ){
			readCnt = width - loadLen;
			row.push_back( RleElement( val, readCnt ) );
			runLen -= readCnt;
			loadLen += readCnt;
		}else{
			row.push_back( RleElement( val, runLen ) );
			loadLen += runLen;
			fscanf( stdin, "%d %d", &val, &runLen );
		}
	}

	//printRow( row );	

	int lines = runLen / width;
	if( lines >= 3 ){	
		assert( state == PENDING );
		zeroCnt = ( lines - 2 )	* width;
		runLen -= zeroCnt;	
		state = READY;
	}

	return true;
}

inline void printResult( Res &res ){
	Res::const_iterator iter;
	PixelVal curVal = -1;
	size_t curCnt = 0;
	for( iter = res.begin(); iter != res.end(); iter ++ ){
		if( iter->val != curVal ){
			if( curVal != -1 ) printf( "%d %d\n", curVal, curCnt );
			curVal = iter->val;
			curCnt = iter->cnt;
			continue;
		}

		curCnt += iter->cnt;
	}

	if( curVal != -1 ) printf( "%d %d\n", curVal, curCnt );
}

inline int accessRow( int idx, Row &row ){
	Row::const_iterator iter;
	int curIdx;
	for( curIdx = 0, iter = row.begin(); iter != row.end(); iter ++ ){
		curIdx += iter->cnt;
		if( curIdx > idx ) return iter->val;
	}

	assert( false );
	return -1;
}

inline int getMaxDiff( int idx, Row *last, Row *current, Row *next, const int & width ){
	assert( idx >= 0 );


	vector<int> diffs;
	PixelVal curVal;
	curVal = accessRow( idx, *current );

	if( idx - 1 >= 0 ){
		//left
		diffs.push_back( abs( accessRow( idx - 1, *current ) - curVal ) );
		
		//upper left
		if( last ) diffs.push_back( abs( accessRow( idx - 1, *last ) - curVal ) );

		//lower left
		if( next ) diffs.push_back( abs( accessRow( idx - 1, *next ) - curVal ) );
	}

	if( idx + 1 <= width - 1 ){
		//right
		diffs.push_back( abs( accessRow( idx + 1, *current ) - curVal ) );

		//upper right
		if( last ) diffs.push_back( abs( accessRow( idx + 1, *last ) - curVal ) );

		//lower right
		if( next ) diffs.push_back( abs( accessRow( idx + 1, *next ) - curVal ) );
	}

	//up
	if( last ) diffs.push_back( abs( accessRow( idx, *last ) - curVal ) );

	//down
	if( next ) diffs.push_back( abs( accessRow( idx, *next ) - curVal ) );

	return *max_element( diffs.begin(), diffs.end() );
}

void calcRow( Row *last, Row *current, Row *next, int &width, Res &res ){
	assert( current && !current->empty() );

	int i;
	
	int idx;
	Row::const_iterator rowIter;
	Row* tmp[3] = { last, current, next };
	typedef list<int> CalcPoints;
	CalcPoints points;
	for( i = 0; i < 3; i++ ){
		if( !tmp[i] ) continue;
		for( idx = 0, rowIter = tmp[i]->begin(); rowIter != tmp[i]->end(); rowIter++ ){
			idx += rowIter->cnt;
			points.push_back( idx - 1 );
		}
	}

	CalcPoints calcIdx;
	CalcPoints::const_iterator ptIter;

	calcIdx.push_back( 0 );
	for( ptIter = points.begin(); ptIter != points.end(); ptIter ++ ){
		calcIdx.push_back( *ptIter );
		if( *ptIter + 1 <= width - 1 ) calcIdx.push_back( *ptIter + 1 );
	}
	
	calcIdx.sort();
	calcIdx.unique();

	int repeat;
	CalcPoints::const_iterator nextIdx;
	for( ptIter = calcIdx.begin(); ptIter != calcIdx.end(); ptIter ++ ){
		res.push_back( RleElement( \
					getMaxDiff( *ptIter, last, current, next, \
						width ),
				       	1 ) );
		
		nextIdx = ++ptIter;
		ptIter --;
		if( nextIdx!= calcIdx.end() ){
			if( *( nextIdx ) - *ptIter < 2 ) continue;
			repeat = *nextIdx - *ptIter - 1;

			res.push_back( \
					RleElement( \
						getMaxDiff( *ptIter + 1, \
							last, current, next, width ), \
						repeat ) \
					);
		}
	}	

}

//FILE *stdin;
int main(void)
{
	//stdin = fopen( "data.txt", "r" );

	int width;
	Row buff[3];
	Row *rows[3];
	Row *tmpRow;
	Res result;

	rows[0] = &buff[0];
	rows[1] = &buff[1];
	rows[2] = &buff[2];

	while (1) {
		fscanf(stdin, "%d", &width);
		if (!width)
			break;
		printf( "%d\n", width );
		result.clear();
		rows[0]->clear();
		rows[1]->clear();
		rows[2]->clear();
		while( getRow( *rows[2], width, result ) ){
			tmpRow = rows[0];
			rows[0] = rows[1];
			rows[1] = rows[2];
			rows[2] = tmpRow;

			if( rows[0]->empty() ) continue;
				
			if( rows[2]->empty() ) 
				calcRow( NULL, rows[0], rows[1], width, result );
			else 
				calcRow( rows[2], rows[0], rows[1], width, result );
		}
		if( !rows[0]->empty() )
			calcRow( rows[0], rows[1], NULL, width, result );
		else
			calcRow( NULL, rows[1], NULL, width, result );

		printResult( result );
		printf( "0 0\n" );
		
	}
	printf( "0\n" );

	//fclose( stdin );
	return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator