题目链接:http://poj.org/problem?id=1475
一组测试数据:
7 3
###
.T.
.S.
#B#
...
...
...
结果:
//解题思路:先判断盒子的四周是不是有空位,如果有,则判断人是否能到达盒子的那一边,能的话,把盒子推到空位处,然后继续
AC代码:
1 //解题思路:先判断盒子的四周是不是有空位,如果有,则判断人是否能到达盒子的那一边,能的话,把盒子推到空位处,然后继续 2 #include<iostream> 3 #include<algorithm> 4 #include<cstdio> 5 #include<cstring> 6 #include<queue> 7 #include<string> 8 #include<cmath> 9 using namespace std; 10 int bx,by,sx,sy,tx,ty; 11 int m,n,dir[][2]={-1,0,1,0,0,-1,0,1};//注意题目要求的是n、s、w、e的顺序,因为这个wa了一次 12 char op[]={'n','s','w','e'}; 13 bool mark[25][25][4];//标记箱子四周的位置时候已被用过 14 int vis[25][25];//标记人走过的位置 15 char map[25][25]; 16 struct BB//盒子 17 { 18 int x,y,SX,SY;//SX,SY表示当前箱子固定了,人所在的位置 19 string ans; 20 }bnow,beed; 21 struct YY//人 22 { 23 int x,y; 24 string ans; 25 }ynow,yeed; 26 char up(char c) 27 { 28 return (c-'a'+'A'); 29 } 30 //aa,bb 表示当前盒子的位置;ss,ee表示起点; 31 bool bfs2(int s,int e,int aa,int bb,int ss,int ee)//寻找当前人,是否能够到达盒子指定的位置; 32 { 33 queue<YY>yy; 34 if(s<0 || s>m || e<0 || e>n || map[s][e] == '#') return false; 35 ynow.x = ss; ynow.y = ee; ynow.ans=""; 36 memset(vis,0,sizeof(vis)); 37 vis[aa][bb] =1;//不能经过盒子 38 vis[ss][ee] = 1;//起点标记为 39 yy.push(ynow); 40 while(!yy.empty()) 41 { 42 ynow = yy.front(); 43 yy.pop(); 44 if(ynow.x == s && ynow.y == e) 45 { 46 return true; 47 } 48 for(int i=0;i<4;i++) 49 { 50 yeed.x = ynow.x+dir[i][0]; 51 yeed.y = ynow.y+dir[i][1]; 52 if(yeed.x>0 && yeed.x<=m && yeed.y>0 && yeed.y<=n && !vis[yeed.x][yeed.y] && map[yeed.x][yeed.y]!='#') 53 { 54 yeed.ans = ynow.ans+op[i];//记录走过的路径 55 vis[yeed.x][yeed.y] = 1; 56 yy.push(yeed); 57 } 58 } 59 } 60 return false; 61 } 62 bool bfs1() 63 { 64 queue<BB>bb; 65 bnow.x = bx;bnow.y=by;bnow.ans=""; 66 bnow.SX = sx;bnow.SY=sy; 67 bb.push(bnow); 68 while(!bb.empty()) 69 { 70 71 bnow=bb.front(); 72 bb.pop(); 73 if(bnow.x == tx && bnow.y==ty) 74 { 75 return true; 76 } 77 for(int i=0;i<4;i++) //盒子周围的四个方向; 78 { 79 beed.x = bnow.x+dir[i][0]; 80 beed.y = bnow.y+dir[i][1]; 81 if(beed.x>0 && beed.x<=m && beed.y>0 && beed.y<=n && !mark[beed.x][beed.y][i] && map[beed.x][beed.y]!='#') 82 { 83 if(bfs2(beed.x-2*dir[i][0],beed.y-2*dir[i][1],bnow.x,bnow.y,bnow.SX,bnow.SY))//如果能推到yeed,则需要判断人是否能到达,它的上一个点; 84 { 85 beed.SX = bnow.x;//推完箱子后,人的位置在箱子上 86 beed.SY = bnow.y; 87 beed.ans=bnow.ans+ynow.ans+up(op[i]);//当前的加上推箱子的加上目前挨着推的; 88 mark[beed.x][beed.y][i] = true; 89 bb.push(beed); 90 } 91 } 92 } 93 } 94 return false; 95 } 96 int main() 97 { 98 int T,k=1; 99 while(scanf("%d %d",&m,&n) && m+n) 100 { 101 memset(mark,false,sizeof(mark)); 102 for(int i=1;i<=m;i++) 103 for(int j=1;j<=n;j++) 104 { 105 scanf(" %c",&map[i][j]); 106 if(map[i][j] == 'S') 107 { 108 sx=i;sy =j; 109 } 110 if(map[i][j] == 'T') 111 { 112 tx = i;ty = j; 113 } 114 if(map[i][j] == 'B') 115 { 116 bx = i;by = j; 117 } 118 } 119 printf("Maze #%d ",k++); 120 if(bfs1()) printf("%s ",bnow.ans.c_str());//少个换行wa了一次 121 else printf("Impossible. "); 122 } 123 return 0; 124 }