大家一定玩过“推箱子”这个经典的游戏。具体规则就是在一个N*M的地图上,有1个玩家、1个箱子、1个目的地以及若干障碍,其余是空地。玩家可以往上下左右4个方向移动,但是不能移动出地图或者移动到障碍里去。如果往这个方向移动推到了箱子,箱子也会按这个方向移动一格,当然,箱子也不能被推出地图或推到障碍里。当箱子被推到目的地以后,游戏目标达成。现在告诉你游戏开始是初始的地图布局,请你求出玩家最少需要移动多少步才能够将游戏目标达成。
输入描述:
每个测试输入包含1个测试用例 第一行输入两个数字N,M表示地图的大小。其中0<N,M<=8。 接下来有N行,每行包含M个字符表示该行地图。其中 . 表示空地、X表示玩家、*表示箱子、#表示障碍、@表示目的地。 每个地图必定包含1个玩家、1个箱子、1个目的地。
输出描述:
输出一个数字表示玩家最少需要移动多少步才能将游戏目标达成。当无论如何达成不了的时候,输出-1。
输入例子1:
4 4 .... ..*@ .... .X.. 6 6 ...#.. ...... #*##.. ..##.# ..X... .@#...
输出例子1:
3 11
思路:BFS,用一个队列记录下每一步人和箱子的位置,实现BFS遍历,用一个四维数组记录下遍历过的点和到达这点时走过的步数,以后不再遍历,最后队列为空即无法到达,输出-1
1 #include<iostream> 2 #include<vector> 3 #include<queue> 4 using namespace std; 5 class State 6 { 7 public: 8 State(int humanX=0, int humanY=0, int boxX=0, int boxY=0) 9 : human_x(humanX) 10 , human_y(humanY) 11 , box_x(boxX) 12 , box_y(boxY) 13 { 14 } 15 int human_x; 16 int human_y; 17 int box_x; 18 int box_y; 19 }; 20 int main() 21 { 22 int N, M; 23 cin>>N>>M; 24 vector<vector<char>> map(N, vector<char>(M, ‘0‘)); 25 int human_x, human_y, box_x, box_y; 26 int end_x, end_y; 27 for(int i=0; i<N; ++i) 28 { 29 for(int j=0; j<M; ++j) 30 { 31 cin>>map[i][j]; 32 if(map[i][j]==‘X‘) 33 { 34 human_x=i; 35 human_y=j; 36 }else if(map[i][j]==‘*‘){ 37 box_x=i; 38 box_y=j; 39 }else if(map[i][j]==‘@‘){ 40 end_x=i; 41 end_y=j; 42 } 43 } 44 } 45 queue<State> que; 46 que.push(State(human_x, human_y, box_x, box_y)); 47 int count[9][9][9][9]={0}; 48 int stepX[4]={1, -1, 0, 0}; 49 int stepY[4]={0, 0, 1, -1}; 50 while(que.size()) 51 { 52 State cur=que.front(); 53 que.pop(); 54 if(cur.box_x==end_x && cur.box_y==end_y){ 55 cout<<count[cur.human_x][cur.human_y][cur.box_x][cur.box_y]<<endl; 56 return 0; 57 } 58 for(int i=0; i<4; ++i) 59 { 60 State next=cur; 61 next.human_x+=stepX[i]; 62 next.human_y+=stepY[i]; 63 if(next.human_x<0 || next.human_x>=N || next.human_y<0 || next.human_y>=M || map[next.human_x][next.human_y]==‘#‘)continue; 64 if(next.human_x==next.box_x && next.human_y==next.box_y){//如果人走到了箱子的位置,那么箱子也按人走的方向移动 65 next.box_x+=stepX[i]; 66 next.box_y+=stepY[i]; 67 if(next.box_x<0 || next.box_x>=N || next.box_y<0 || next.box_y>=M || map[next.box_x][next.box_y]==‘#‘)continue; 68 } 69 if(count[next.human_x][next.human_y][next.box_x][next.box_y])continue;//如果之前遍历过,则不再遍历 70 count[next.human_x][next.human_y][next.box_x][next.box_y]=count[cur.human_x][cur.human_y][cur.box_x][cur.box_y]+1; 71 que.push(next); 72 } 73 } 74 cout<<-1<<endl; 75 return 0; 76 }