/*
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;
}