⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 acm101.cpp

📁 ACM online judgement 101 一個解決堆積箱子的演算法
💻 CPP
字号:
/* 
	ACM 101
*/

#include <iostream>

using namespace std;

class Block {
	public:
		Block( int i )
		{
			myNum = i;
			CurrentNum = i;
			Nstacks = 0;
			Stacks = new Block*[ 24 ];
			MyBase = this;
		}
		
		void ReturningMe() {
			CurrentNum = myNum;
			Nstacks = 0;
			MyBase = this;
		}
		
		void ReturningStacks() {
			for( int i = 0; i < Nstacks; ++i ) {
				Stacks[ i ]->ReturningMe();
			}
			Nstacks = 0;
		}
		
		void StackLeave(bool MeLeave) {
			if ( MyBase != this ) {
				MyBase->Nstacks -= ( ( int )MeLeave + 1 );
				for( int i = 0; i < MyBase->Nstacks; ++i ) {
					if( MyBase->Stacks[ i ] == this ) break;
						MyBase->Stacks[ i ]->Nstacks -= ( ( int )MeLeave + 1 );
				}
			}
		}
		
		int myNum;
		int CurrentNum;
		int Nstacks;
		Block **Stacks;
		Block *MyBase;
};

struct instruction {
	char action[5];
	char style[5];
	int a;
	int b;
};

bool Parse(struct instruction &o) {
	cin >> o.action;
	if( !strcmp( o.action, "quit" ) ) return false;
	cin >> o.a;
	cin >> o.style;
	cin >> o.b;
	return true;
};

/* move onto */
bool operator-( Block &a, Block &b )
{

	//  puts block a onto block b after returning any blocks that are stacked on top of blocks a and b to their initial positions. 
	a.StackLeave(true);
	a.ReturningStacks();
	
	b.StackLeave(false);
	b.ReturningStacks();
	
	b.Nstacks = 1;
	b.Stacks[ 0 ] = &a;
	a.CurrentNum = b.CurrentNum;
	a.MyBase = b.MyBase;
	if( b.MyBase != &b ) {
		b.MyBase->Nstacks += 1;
		b.MyBase->Stacks[ b.MyBase->Nstacks - 1 ] = &a;
		for( int i = 0; i < b.MyBase->Nstacks; ++i ) {
			if( b.MyBase->Stacks[ i ] == &b ) break;
			b.MyBase->Stacks[ i ]->Nstacks += 1;
			b.MyBase->Stacks[ b.MyBase->Stacks[ i ]->Nstacks - 1 ] = &a;
		}
	}
	
	return true;
}

/*  move over  */
bool operator-=( Block &a, Block &b )
{
	
	// puts block a onto the top of the stack containing block b, after returning any blocks that are stacked on top of block a to their initial positions. 
	
	a.StackLeave(true);
	a.ReturningStacks();
	
	b.Nstacks += 1;
	b.Stacks[ b.Nstacks - 1 ] = &a;
	a.CurrentNum = b.CurrentNum;
	a.MyBase = b.MyBase;
	if ( b.MyBase != &b ) {
		b.MyBase->Nstacks += 1;
		b.MyBase->Stacks[ b.MyBase->Nstacks - 1 ] = &a;
		for( int i = 0; i < b.MyBase->Nstacks; ++i ) {
			if( b.MyBase->Stacks[ i ] == &b ) break;
			b.MyBase->Stacks[ i ]->Nstacks += 1;
			b.MyBase->Stacks[ b.MyBase->Stacks[ i ]->Nstacks - 1 ] = &a;
		}
	}
	return true;
}

/*  pile onto  */
bool operator|( Block &a, Block &b )
{
	
	// moves the pile of blocks consisting of block a, and any blocks that are stacked above block a, onto block b. All blocks on top of block b are moved to their initial positions prior to the pile taking place. The blocks stacked above block a retain their order when moved. 
	
	b.StackLeave(false);
	b.ReturningStacks();
	
	b.Nstacks = 1;
	b.Stacks[ 0 ] = &a;
	a.CurrentNum = b.CurrentNum;
	a.MyBase = b.MyBase;
	
	for( int i = 0; i < a.Nstacks; ++i ) {
		a.Stacks[ i ]->CurrentNum = b.CurrentNum;
		a.Stacks[ i ]->MyBase = b.MyBase;
	}
	
	if( b.MyBase != & b ) {
		b.MyBase->Nstacks += 1;
		b.MyBase->Stacks[ b.MyBase->Nstacks - 1 ] = &a;
		for( int i = 0; i < a.Nstacks; ++i ){
			b.MyBase->Nstacks += 1;
			b.MyBase->Stacks[ b.MyBase->Nstacks - 1 ] = a.Stacks[ i ];
		}
		
		for( int i = 0; i < b.MyBase->Nstacks; ++i ) {
			if( b.MyBase->Stacks[ i ] == &b ) break;
			b.MyBase->Stacks[ i ]->Nstacks += 1;
			b.MyBase->Stacks[ i ]->Stacks[ b.MyBase->Stacks[ i ]->Nstacks - 1 ] = &a;
			for( int j = 0; j < a.Nstacks; ++j ) {
				b.MyBase->Stacks[ i ]->Nstacks += 1;
				b.MyBase->Stacks[ i ]->Stacks[ b.MyBase->Stacks[ i ]->Nstacks - 1 ] = a.Stacks[ j ];
			}
		}
		
	}

	return true;
}

/*  pile over  */
bool operator|=( Block &a, Block &b )
{
	
	// puts the pile of blocks consisting of block a, and any blocks that are stacked above block a, onto the top of the stack containing block b. The blocks stacked above block a retain their original order when moved. 
	
	b.Nstacks += 1;
	b.Stacks[ b.Nstacks - 1 ] = &a;
	a.CurrentNum = b.CurrentNum;
	a.MyBase = b.MyBase;
	
	for( int i = 0; i < a.Nstacks; ++i ) {
		a.Stacks[ i ]->CurrentNum = b.CurrentNum;
		a.Stacks[ i ]->MyBase = b.MyBase;
	}
	
	if( b.MyBase != & b ) {
		b.MyBase->Nstacks += 1;
		b.MyBase->Stacks[ b.MyBase->Nstacks - 1 ] = &a;
		for( int i = 0; i < a.Nstacks; ++i ){
			b.MyBase->Nstacks += 1;
			b.MyBase->Stacks[ b.MyBase->Nstacks - 1 ] = a.Stacks[ i ];
		}
		
		for( int i = 0; i < b.MyBase->Nstacks; ++i ) {
			if( b.MyBase->Stacks[ i ] == &b ) break;
			b.MyBase->Stacks[ i ]->Nstacks += 1;
			b.MyBase->Stacks[ i ]->Stacks[ b.MyBase->Stacks[ i ]->Nstacks - 1 ] = &a;
			for( int j = 0; j < a.Nstacks; ++j ) {
				b.MyBase->Stacks[ i ]->Nstacks += 1;
				b.MyBase->Stacks[ i ]->Stacks[ b.MyBase->Stacks[ i ]->Nstacks - 1 ] = a.Stacks[ j ];
			}
		}
		
	}	
	return true;
}

int main()
{
	int Num_Block;
	struct instruction ReadIn;
	
	cin >> Num_Block;
	Block **Blocks = new Block*[ Num_Block ];
	for( int i = 0; i < Num_Block; ++i ) {
		Blocks[ i ] = new Block( i );
	}
	
	bool Valid;
	
	while( Parse( ReadIn ) ) {
		Valid = true;
		
		if( ReadIn.a == ReadIn.b ) Valid = false;
		
		for( int i = 0; i < Blocks[ ReadIn.a ]->Nstacks; ++i ) {
			if( Blocks[ ReadIn.a ]->Stacks[ i ]->CurrentNum == ReadIn.b ) {
				Valid = false;
				break;
			}
		}
		for( int i = 0; i < Blocks[ ReadIn.b ]->Nstacks; ++i ) {
			if( Blocks[ ReadIn.b ]->Stacks[ i ]->CurrentNum == ReadIn.a ) {
				Valid = false;
				break;
			}
		}
		
		if( Valid == false ) continue;
		
		if( strcmp( ReadIn.action, "move" ) == 0 ) {
			if( strcmp( ReadIn.style, "onto" ) == 0 ) {
				*Blocks[ ReadIn.a ] - *Blocks[ ReadIn.b ];
			}else if(strcmp( ReadIn.style, "over" ) == 0 ) {
				*Blocks[ ReadIn.a ] -= *Blocks[ ReadIn.b ];
			}
		}else if( strcmp( ReadIn.action, "pile" ) == 0 ) {
			if( strcmp( ReadIn.style, "onto" ) == 0 ) {
				*Blocks[ ReadIn.a ] | *Blocks[ ReadIn.b ];
			}else if(strcmp( ReadIn.style, "over" ) == 0 ) {
				*Blocks[ ReadIn.a ] |= *Blocks[ ReadIn.b ];
			}
		}
	}
	
	for( int i = 0; i < Num_Block; ++i ) {
		cout << i << ":" ;
		for( int j = 0; j < Num_Block; ++j ) {
			if( Blocks[ j ]->CurrentNum == i && Blocks[ j ]->MyBase == Blocks[ j ] ) {
				cout << " " << Blocks[ j ]->myNum;
				for( int k = 0; k < ( Blocks[ j ]->Nstacks ); ++k ) {
					cout << " " << Blocks[ j ]->Stacks[ k ]->myNum;
				}
				break;
			}
		}
		cout << endl;
	}
	
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -