擰魔方問題-模擬法

問題描述:魔方是一種常見的玩具。2010年7月,美國加利福尼亞州科學家利用計算機證明任意組合的魔方均可以在20步之內還原。作爲一個入門級的程序員,我們決定先寫一個驗證魔方是否復原的程序。對於魔方的一個操作,我們用一個字母來表示。將魔方的一個面正對玩家,就有了前後上下左右六個面,分別用F(Front),B(Back),U(Up),D(Down):,L(Left),R(Right)來表示將這個面順時針旋轉90度,具體玩魔方的時候將右手覆蓋到對應的面上,這六個操作時右手的旋轉方向都是相同的。同時用X,Y,Z,表示順時針旋轉中間一層,分別對應U,R,F。具體情況可以參照下圖。與這九個操作對應的還有f,b,u,d,l,r,x,y,z,表示逆時針旋轉。

現在我們給出一個操作序列,問在這麼旋轉之後,魔方是否和原來的時候完全一樣。比如UXd被認爲是不一樣。輸入爲一個長度不超過200的字符串,僅包含之上定義的18個字母。如果能復原,輸出Yes,否則輸出No。


測試用例輸入:RUur
測試用例輸出:Yes


#include<stdio.h>

char Cube[6][9];

void Init  ( void );
void Front ( void );
void Back  ( void );
void Up    ( void );
void Down  ( void );
void Left  ( void );
void Right ( void );
void X     ( void );
void Y     ( void );
void Z     ( void );

int main( )
{
	int  i , j ;
	char ch;

	Init( );

	while( (ch=getchar())!='\n' )
	{
		if( ch=='F' )
			Front( );

		else if( ch=='B' )
			Back( );
	
		else if( ch=='U' )
			Up( );

		else if( ch=='D' )
			Down( );

		else if( ch=='L' )
			Left( );

		else if( ch=='R' )
			Right( );

		else if( ch=='X' )
			X( );

		else if( ch=='Y' )
			Y( );

		else if( ch=='Z' )
			Z( );

		else if( ch=='f' )
		{
			for( i=1 ; i<=3 ; i++ )
				Front( );
		}

		else if( ch=='b' )
		{
			for( i=1 ; i<=3 ; i++ )
			Back( );
		}

		else if( ch=='u' )
		{
			for( i=1 ; i<=3 ; i++ )
				Up( );
		}

		else if( ch=='d' )
		{
			for( i=1 ; i<=3 ; i++ )
				Down( );
		}

		else if( ch=='l' )
		{
			for( i=1 ; i<=3 ; i++ )
				Left( );
		}

		else if( ch=='r' )
		{
			for( i=1 ; i<=3 ; i++ )
				Right( );
		}

		else if( ch=='x' )
		{
			for( i=1 ; i<=3 ; i++ )
				X( );
		}

		else if( ch=='y' )
		{
			for( i=1 ; i<=3 ; i++ )
				Y( );
		}

		else if( ch=='z' )
		{
			for( i=1 ; i<=3 ; i++ )
				Z( );
		}
	}

	for( i=0 ; i<6 ; i++ )
	{
		for( j=0 ; j<9 ; j++ )
			if( Cube[i][j] != Cube[i][0] )
			{
				printf("No\n");

				return 0;
			}
	}

	printf("Yes\n");
	
	return 0;
}


void Init( void )
{
	int i , j , k=1;

	for( i=0 , k=1 ; i<6 ; i++ , k++ )
	{
		for( j=0 ; j<9 ; j++ )
			Cube[i][j] = k;
	}
}


void Front( void )
{
	int k , j , Color[12];

	for( k=0 ; k<9 ; k++ )
		Color[k] = Cube[0][k];

	Cube[0][0] = Color[6];
	Cube[0][1] = Color[3];
	Cube[0][2] = Color[0];

	Cube[0][3] = Color[7];
	Cube[0][4] = Color[4];
	Cube[0][5] = Color[1];

	Cube[0][6] = Color[8];
	Cube[0][7] = Color[5];
	Cube[0][8] = Color[2];

	k=0;

	for( j=6 ; j<9 ; j++ )
		Color[k++] = Cube[4][j];

	for( j=0  ; j<9 ; j+=3 )
		Color[k++] = Cube[3][j];

	for( j=8 ; j>0 ; j-=3 )
		Color[k++] = Cube[5][j];

	for( j=8 ; j>0 ; j-=3 )
		Color[k++] = Cube[2][j];

	k=0;

	Cube[3][0] = Color[k++];
	Cube[3][3] = Color[k++];
	Cube[3][6] = Color[k++];

	Cube[5][8] = Color[k++];
	Cube[5][5] = Color[k++];
	Cube[5][2] = Color[k++];

	Cube[2][8] = Color[k++];
	Cube[2][5] = Color[k++];
	Cube[2][2] = Color[k++];

	Cube[4][6] = Color[k++];
	Cube[4][7] = Color[k++];
	Cube[4][8] = Color[k++];
}



void Back( void )
{
	int k , j , Color[12];

	for( k=0 ; k<9 ; k++ )
		Color[k] = Cube[1][k];

	Cube[1][0] = Color[6];
	Cube[1][1] = Color[3];
	Cube[1][2] = Color[0];

	Cube[1][3] = Color[7];
	Cube[1][4] = Color[4];
	Cube[1][5] = Color[1];

	Cube[1][6] = Color[8];
	Cube[1][7] = Color[5];
	Cube[1][8] = Color[2];

	k=0;

	for( j=2 ; j>=0 ; j-- )
		Color[k++] = Cube[4][j];

	for( j=0  ; j<9 ; j+=3 )
		Color[k++] = Cube[2][j];

	for( j=0  ; j<9 ; j+=3 )
		Color[k++] = Cube[5][j];

	for( j=8 ; j>0 ; j-=3 )
		Color[k++] = Cube[3][j];

	k=0;

	Cube[2][0] = Color[k++];
	Cube[2][3] = Color[k++];
	Cube[2][6] = Color[k++];

	Cube[5][0] = Color[k++];
	Cube[5][3] = Color[k++];
	Cube[5][6] = Color[k++];

	Cube[3][8] = Color[k++];
	Cube[3][5] = Color[k++];
	Cube[3][2] = Color[k++];

	Cube[4][2] = Color[k++];
	Cube[4][1] = Color[k++];
	Cube[4][0] = Color[k++];
}


void Up( void )
{
	int k , j , Color[12];

	for( k=0 ; k<9 ; k++ )
		Color[k] = Cube[4][k];

	Cube[4][0] = Color[6];
	Cube[4][1] = Color[3];
	Cube[4][2] = Color[0];

	Cube[4][3] = Color[7];
	Cube[4][4] = Color[4];
	Cube[4][5] = Color[1];

	Cube[4][6] = Color[8];
	Cube[4][7] = Color[5];
	Cube[4][8] = Color[2];

	k=0;

	for( j=2 ; j>=0 ; j-- )
		Color[k++] = Cube[0][j];

	for( j=2  ; j>=0 ; j-- )
		Color[k++] = Cube[2][j];

	for( j=2  ; j>=0 ; j-- )
		Color[k++] = Cube[1][j];

	for( j=2  ; j>=0 ; j-- )
		Color[k++] = Cube[3][j];

	k=0;

	Cube[2][2] = Color[k++];
	Cube[2][1] = Color[k++];
	Cube[2][0] = Color[k++];

	Cube[1][2] = Color[k++];
	Cube[1][1] = Color[k++];
	Cube[1][0] = Color[k++];

	Cube[3][2] = Color[k++];
	Cube[3][1] = Color[k++];
	Cube[3][0] = Color[k++];

	Cube[0][2] = Color[k++];
	Cube[0][1] = Color[k++];
	Cube[0][0] = Color[k++];
}


void Down( void )
{
	int k , j , Color[12];

	for( k=0 ; k<9 ; k++ )
		Color[k] = Cube[5][k];

	Cube[5][0] = Color[6];
	Cube[5][1] = Color[3];
	Cube[5][2] = Color[0];

	Cube[5][3] = Color[7];
	Cube[5][4] = Color[4];
	Cube[5][5] = Color[1];

	Cube[5][6] = Color[8];
	Cube[5][7] = Color[5];
	Cube[5][8] = Color[2];

	k=0;

	for( j=6 ; j<=8 ; j++ )
		Color[k++] = Cube[0][j];

	for( j=6 ; j<=8 ; j++ )
		Color[k++] = Cube[3][j];

	for( j=6 ; j<=8 ; j++ )
		Color[k++] = Cube[1][j];

	for( j=6 ; j<=8 ; j++ )
		Color[k++] = Cube[2][j];

	k=0;

	Cube[3][6] = Color[k++];
	Cube[3][7] = Color[k++];
	Cube[3][8] = Color[k++];

	Cube[1][6] = Color[k++];
	Cube[1][7] = Color[k++];
	Cube[1][8] = Color[k++];

	Cube[2][6] = Color[k++];
	Cube[2][7] = Color[k++];
	Cube[2][8] = Color[k++];

	Cube[0][6] = Color[k++];
	Cube[0][7] = Color[k++];
	Cube[0][8] = Color[k++];
}


void Left( void )
{
	int k , j , Color[12];

	for( k=0 ; k<9 ; k++ )
		Color[k] = Cube[2][k];

	Cube[2][0] = Color[6];
	Cube[2][1] = Color[3];
	Cube[2][2] = Color[0];

	Cube[2][3] = Color[7];
	Cube[2][4] = Color[4];
	Cube[2][5] = Color[1];

	Cube[2][6] = Color[8];
	Cube[2][7] = Color[5];
	Cube[2][8] = Color[2];

	k=0;

	for( j=0 ; j<9 ; j+=3 )
		Color[k++] = Cube[4][j];

	for( j=0 ; j<9 ; j+=3 )
		Color[k++] = Cube[0][j];

	for( j=2 ; j>=0 ; j-- )
		Color[k++] = Cube[5][j];

	for( j=8 ; j>=0 ; j-=3 )
		Color[k++] = Cube[1][j];

	k=0;

	Cube[0][0] = Color[k++];
	Cube[0][3] = Color[k++];
	Cube[0][6] = Color[k++];

	Cube[5][2] = Color[k++];
	Cube[5][1] = Color[k++];
	Cube[5][0] = Color[k++];

	Cube[1][8] = Color[k++];
	Cube[1][5] = Color[k++];
	Cube[1][2] = Color[k++];

	Cube[4][0] = Color[k++];
	Cube[4][3] = Color[k++];
	Cube[4][6] = Color[k++];
}


void Right( void )
{
	int k , j , Color[12];

	for( k=0 ; k<9 ; k++ )
		Color[k] = Cube[3][k];

	Cube[3][0] = Color[6];
	Cube[3][1] = Color[3];
	Cube[3][2] = Color[0];

	Cube[3][3] = Color[7];
	Cube[3][4] = Color[4];
	Cube[3][5] = Color[1];

	Cube[3][6] = Color[8];
	Cube[3][7] = Color[5];
	Cube[3][8] = Color[2];

	k=0;

	for( j=8 ; j>=0 ; j-=3 )
		Color[k++] = Cube[4][j];

	for( j=0 ; j<9 ; j+=3 )
		Color[k++] = Cube[1][j];

	for( j=6 ; j<9 ; j++ )
		Color[k++] = Cube[5][j];

	for( j=8 ; j>=0 ; j-=3 )
		Color[k++] = Cube[0][j];

	k=0;

	Cube[1][0] = Color[k++];
	Cube[1][3] = Color[k++];
	Cube[1][6] = Color[k++];

	Cube[5][6] = Color[k++];
	Cube[5][7] = Color[k++];
	Cube[5][8] = Color[k++];

	Cube[0][8] = Color[k++];
	Cube[0][5] = Color[k++];
	Cube[0][2] = Color[k++];

	Cube[4][8] = Color[k++];
	Cube[4][5] = Color[k++];
	Cube[4][2] = Color[k++];
}


void X( void )
{
	int k , j , Color[12];

	k=0;

	for( j=5 ; j>=3 ; j-- )
		Color[k++] = Cube[0][j];

	for( j=5 ; j>=3 ; j-- )
		Color[k++] = Cube[2][j];

	for( j=5 ; j>=3 ; j-- )
		Color[k++] = Cube[1][j];

	for( j=5 ; j>=3 ; j-- )
		Color[k++] = Cube[3][j];

	k=0;

	Cube[2][5] = Color[k++];
	Cube[2][4] = Color[k++];
	Cube[2][3] = Color[k++];

	Cube[1][5] = Color[k++];
	Cube[1][4] = Color[k++];
	Cube[1][3] = Color[k++];

	Cube[3][5] = Color[k++];
	Cube[3][4] = Color[k++];
	Cube[3][3] = Color[k++];

	Cube[0][5] = Color[k++];
	Cube[0][4] = Color[k++];
	Cube[0][3] = Color[k++];
}


void Y( void )
{
	int k , j , Color[12];

	k=0;

	for( j=7 ; j>=0 ; j-=3 )
		Color[k++] = Cube[4][j];

	for( j=1 ; j<9 ; j+=3 )
		Color[k++] = Cube[1][j];

	for( j=3 ; j<=5 ; j++ )
		Color[k++] = Cube[5][j];

	for( j=7 ; j>=0 ; j-=3 )
		Color[k++] = Cube[0][j];

	k=0;

	Cube[1][1] = Color[k++];
	Cube[1][4] = Color[k++];
	Cube[1][7] = Color[k++];

	Cube[5][3] = Color[k++];
	Cube[5][4] = Color[k++];
	Cube[5][5] = Color[k++];

	Cube[0][7] = Color[k++];
	Cube[0][4] = Color[k++];
	Cube[0][1] = Color[k++];

	Cube[4][7] = Color[k++];
	Cube[4][4] = Color[k++];
	Cube[4][1] = Color[k++];
}


void Z( void )
{
	int k , j , Color[12];

	k=0;

	for( j=3 ; j<=5 ; j++ )
		Color[k++] = Cube[4][j];

	for( j=1 ; j<9 ; j+=3 )
		Color[k++] = Cube[3][j];

	for( j=7 ; j>=0 ; j-=3 )
		Color[k++] = Cube[5][j];

	for( j=7 ; j>=0 ; j-=3 )
		Color[k++] = Cube[2][j];

	k=0;

	Cube[3][1] = Color[k++];
	Cube[3][4] = Color[k++];
	Cube[3][7] = Color[k++];

	Cube[5][7] = Color[k++];
	Cube[5][4] = Color[k++];
	Cube[5][1] = Color[k++];

	Cube[2][7] = Color[k++];
	Cube[2][4] = Color[k++];
	Cube[2][1] = Color[k++];

	Cube[4][3] = Color[k++];
	Cube[4][4] = Color[k++];
	Cube[4][5] = Color[k++];
}

代碼分析:採用了模擬法的算法,代碼結構流程非常清晰,思路簡單,就是根據題目所示的意思來模擬要解決問題的步驟,一個簡單的方法就是拿一個真正的魔方或者紙質的方體,並標上數字,這樣比起純空間想象要容易得多,錯誤率得以降低,不過代碼的18的函數定義非常相似,可想方法來給予優化。請問大家這裏有什麼更好的算法或者可以優化這18個函數儘量簡潔一點的方法麼?



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