藍橋杯BFS 移動方格的問題

              這道題好像是某一屆高職高專的最後一題,原題如下:
/*
10. 移動字母
2x3=6個方格中放入ABCDE五個字母,右下角的那個格空着。如圖1所示。
和空格子相鄰的格子中的字母可以移動到空格中,比如,圖中的C和E就可以移動,移動後的局面分別是:
A B  
D E C

A B C
D E

  爲了表示方便,我們把6個格子中字母配置用一個串表示出來,比如上邊的兩種局面分別表示爲:
AB*DEC
ABCD*E
  題目的要求是:請編寫程序,由用戶輸入若干表示局面的串,程序通過計算,輸出是否能通過對初始狀態經過若干次移動到達該狀態。可以實現輸出1,否則輸出0。初始狀態爲:ABCDE*
  用戶輸入的格式是:先是一個整數n,表示接下來有n行狀態。程序輸出也應該是n行1或0
  例如,用戶輸入:
3
ABCDE*
AB*DEC
CAED*B

  則程序應該輸出:
1
1
0
*/

解題思路分析:  根據題目分析可知,每次能否移動某個方格的關鍵就是* 的位置,根據*的不同位置有不同的移動方法,而且每次移動可能都能有新的狀態產生,當然可能會重複,由於每次都只能和* 相鄰的位置元素交換而且要避免和前面的已經有過的狀態重複,所以我當時拿到題目使用的是BFS搜索,我的思路是這樣的:

                首先我有一個隊列,(char queue[710][6];  // 定義一個隊列  總共排列710 總不可能超過710總情況),初始時放入ABCDE*   開始隊列下標index指向初始情況隊列總數countqueue=1如圖:

開始的排列:

所以可以將2號和5號對換  得到  AB*DEC (沒有出現過,入隊列),也可以將4號和5號兌換  得到ABCD*E(沒有出現 ,入隊列)

此時隊列的情況:

經過一次變化之後index加1   countqueue=3指向AB*DEC

此時可以將1,2   或則 2,5對換分別得到A*BDEC(沒出現,入隊列)  和 ABCDE*(重複,捨去)此次操作之後隊列的index爲2,countqueue=4:,如下圖:


按照此步奏不斷的重複 知道 index>=countqueue循環截止

程序代碼如下(打印出所有可能移到的結果):

#include <cstdlib>
#include <iostream>
#include<algorithm>
//  藍橋杯移動方格的問題 
using namespace std;
char queue[710][6];  // 定義一個隊列
 int countqueue;  // 記錄隊列的長度 
int getIndex(char *a)  // 找到* 的下標
{   int result=0;
    for(int i=0;i<6;i++)
		if(a[i]=='*')					
		{
		    result=i;
			break;             						 
		}
    return result;                   
} 
bool equals(char *a,char *b)  // 判斷兩個字符串是否相等 
{
     bool sign=true;
     for(int i=0;i<6;i++)
         if(a[i]!=b[i])
         {
			sign=false;
			break;															
          } 
    return sign;
 }
 bool inQueue(char *a)  // 判斷字符串是否存在隊列中
 {
	bool sign=false;  // 不存在 
	for(int i=0;i<countqueue;i++)
		if(equals(a,queue[i]))
		{ 
			sign=true;  // 存在
			break;
		}
	return sign; 
} 
 void pushqueue(char *a)  // 進隊列 
 {
	for(int i=0;i<6;i++)
		queue[countqueue][i]=a[i];
	countqueue++;	
} 
char* swap(char* a,int m,int n) // 將m,n 下標的字符對換 
{
	char* result=new char[6];
	for(int i=0;i<6;i++)
		result[i]=a[i];
	char t=result[m];
	result[m]=result[n];
	result[n]=t;
	return result; 
}

void getAllPerm()  // 得到所有的排列 
{
	int i=0;
	while(i<countqueue)
	{
		int index=getIndex(queue[i]);  // 得到當前串中* 的下標
		char* swapchar;  // 通過交換得到的字符串 
		switch(index)   //  根據* 號的下標  進行字符串的交換 
		{	
			
			case 0:	swapchar=swap(queue[i],0,1);
					if(!inQueue(swapchar))  // 如果字符串不在隊列中,則加入到隊列中 
						pushqueue(swapchar);
					swapchar=swap(queue[i],0,3);
					if(!inQueue(swapchar))
						pushqueue(swapchar);
					break;   //  錯誤 原因 
			case 1: swapchar=swap(queue[i],0,1);
				
					if(!inQueue(swapchar))
						pushqueue(swapchar);
					swapchar=swap(queue[i],2,1);
					if(!inQueue(swapchar))
						pushqueue(swapchar);
					swapchar=swap(queue[i],4,1);
					if(!inQueue(swapchar))
						pushqueue(swapchar);
					break;   //  錯誤 原因 
			case 2:	
					swapchar=swap(queue[i],2,1);
					if(!inQueue(swapchar))
						pushqueue(swapchar);
					swapchar=swap(queue[i],2,5);
					if(!inQueue(swapchar))
						pushqueue(swapchar);
					break;   //  錯誤 原因 
			case 3:	swapchar=swap(queue[i],3,0);
					if(!inQueue(swapchar))
						pushqueue(swapchar);
					swapchar=swap(queue[i],3,4);
					if(!inQueue(swapchar))
						pushqueue(swapchar);
					break;   //  錯誤 原因 
			case 4: swapchar=swap(queue[i],4,1);
					if(!inQueue(swapchar))
						pushqueue(swapchar);
					swapchar=swap(queue[i],4,3);
					if(!inQueue(swapchar))
						pushqueue(swapchar);
					swapchar=swap(queue[i],4,5);
					if(!inQueue(swapchar))
						pushqueue(swapchar);
					break;   //  錯誤 原因 
			case 5:	swapchar=swap(queue[i],5,4);
					if(!inQueue(swapchar))
						pushqueue(swapchar);
					swapchar=swap(queue[i],5,2);
					if(!inQueue(swapchar))
						pushqueue(swapchar);
					break;   //  錯誤 原因 
		} 
		i++;
	} 
} 
int main(int argc, char *argv[])
{
    int n;
   	char a[7]="abcde*";
   	pushqueue(a);
   	getAllPerm();
   	cout<<"print: queue"<<endl;
	for(int i=0;i<countqueue;i++)
	{
		for(int j=0;j<6;j++)
			cout<<queue[i][j]<<"  ";
		cout<<endl;
	}
   cout<<"共有"<<countqueue<<"條合格的記錄"<<endl; 
    cin>>n;
    int *result=new int[n];
    for(int i=0;i<n;i++)
    {
		char test[6];
		fflush(stdin);
		for(int j=0;j<6;j++)
			cin>>test[j];
		if(inQueue(test))
			result[i]=1;
		else
			result[i]=0;	
	}
	for(int i=0;i<n;i++)
	{
		cout<<result[i]<<endl;
	}

	
	
	/* 
	cout<<"print: queue"<<endl;
	for(int i=0;i<countqueue;i++)
	{
		for(int j=0;j<6;j++)
			cout<<queue[i][j]<<"  ";
	
		cout<<endl;
	}*/
	system("pause");
    return EXIT_SUCCESS;
}



發佈了47 篇原創文章 · 獲贊 4 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章