移动字母(广度搜索+队列)

移动字母
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
 
解题思路:这道题,就是利用将‘*’移动到可以移动的位置,然后将此状态存入队列之中。进行广搜,直到搜到原始状态为止。
 
解题代码:
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 }

 

posted on 2013-05-06 19:05  nigel_jw  阅读(238)  评论(0)    收藏  举报

导航