移动字母(广度搜索+队列)
移动字母
2x3=6个方格中放入ABCDE五个字母,右下角的那个格空着。如图所示。
和空格子相邻的格子中的字母可以移动到空格中,比如,图中的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
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
解题思路:这道题,就是利用将‘*’移动到可以移动的位置,然后将此状态存入队列之中。进行广搜,直到搜到原始状态为止。
解题代码:
View Code
1 #include<iostream> 2 #include<string.h> 3 #include<queue> 4 using namespace std; 5 6 typedef struct //存放状态 7 { 8 char st[2][4]; 9 }map; 10 map ini; 11 map vis[50000]; 12 int Count; 13 int dx[4] = {0,1,0,-1};//方向数组 14 int dy[4] = {1,0,-1,0}; 15 16 int bfs(map &temp , int i , int j , int k) 17 { 18 int x = j , y = k; 19 x = x + dx[i]; 20 y = y + dy[i]; 21 if(x<0 || x>1 || y<0 || y>2) return 0; //越界 22 char ch; 23 ch = temp.st[j][k]; 24 temp.st[j][k] = temp.st[x][y]; 25 temp.st[x][y] = ch; 26 return 1; 27 } 28 29 int find(map temp) //判断是否标记 30 { 31 int i; 32 for(i = 0; i < Count; i++) 33 if(!(strcmp(temp.st[0] , vis[i].st[0]) || strcmp(temp.st[0] , vis[i].st[0]))) 34 return 0; 35 return 1; 36 } 37 38 int equal(map temp) //判断是否回到标准状态 39 { 40 if(!(strcmp(temp.st[0] , ini.st[0]) || strcmp(temp.st[0] , ini.st[0]))) 41 return 1; 42 else return 0; 43 } 44 45 int main() 46 { 47 int n , i , j , k , flag; 48 map m; 49 cin>>n; 50 strcpy(ini.st[0],"ABC"); //初始化 51 strcpy(ini.st[1],"DE*"); 52 while(n--) 53 { 54 queue<map>q; 55 Count = 0; 56 flag = 0; 57 getchar(); 58 for(i = 0; i < 2; i++) 59 for(j = 0; j < 3; j++) 60 cin>>m.st[i][j]; 61 m.st[0][3] = '\0'; 62 m.st[1][3] = '\0'; 63 q.push(m); 64 vis[Count++] = q.front(); //标记状态 65 while(!q.empty()) 66 { 67 map temp1; 68 temp1 = q.front(); 69 q.pop(); //将此状态出队列 70 if(equal(temp1)) 71 { 72 flag = 1; 73 break; 74 } 75 for(j = 0; j < 2; j++) //寻找‘*’ 76 for(k = 0; k < 3; k++) 77 if(temp1.st[j][k] == '*') 78 goto loop; 79 loop: for(i = 0; i <4; i++) //四个方向 80 { 81 map temp2 = temp1; 82 if(bfs(temp1 , i , j , k)) //广搜 83 { 84 if(find(temp1)) 85 { 86 q.push(temp1); 87 vis[Count++] = temp1; 88 } 89 } 90 } 91 } 92 if(flag) cout<<'1'<<endl; 93 else cout<<'0'<<endl; 94 } 95 return 0; 96 }
既然选择了这条路,就应该坚持下去。

浙公网安备 33010602011771号