Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
Re:做题总结以及注意事项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: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator