网易笔试题:推箱子

大家一定玩过“推箱子”这个经典的游戏。具体规则就是在一个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 }

 

 

posted @ 2018-03-19 18:22  jeysin  阅读(557)  评论(0编辑  收藏  举报