题目:大家一定玩过“推箱子”这个经典的游戏。具体规则就是在一个N*M的地图上,有1个玩家、1个箱子、1个目的地以及若干障碍,其余是空地。玩家可以往上下左右4个方向移动,但是不能移动出地图或者移动到障碍里去。如果往这个方向移动推到了箱子,箱子也会按这个方向移动一格,当然,箱子也不能被推出地图或推到障碍里。当箱子被推到目的地以后,游戏目标达成。现在告诉你游戏开始是初始的地图布局,请你求出玩家最少需要移动多少步才能够将游戏目标达成。
输入描述:
每个测试样例包含一组数据。
第一行输入两个数字N,M表示地图的大小。其中0<N,M<=8。
接下来有N行,每行包含M个字符表示该行地图。其中 . 表示空地、X表示玩家、*表示箱子、#表示障碍、@表示目的地。
每个地图必定包含1个玩家、1个箱子、1个目的地。
输出描述:
输出一个数字表示玩家最少需要移动多少步才能将游戏目标达成。当无论如何达成不了的时候,输出-1。
输入例子:
4 4 .... ..*@ .... .X.. 6 6 ...#.. ...... #*##.. ..##.# ..X... .@#...
输出例子:
3 11思路:该题目就是搜索问题,用BFS求解。将箱子和玩家的位置看成整体,来进行BFS。
代码:
#include<iostream>
#include<stdio.h>
#include<queue>
using namespace std;
struct state{
int x, y, xb, yb;
state(int x, int y, int xb, int yb) :x(x), y(y), xb(xb), yb(yb){}
};
class Solution{
public:
Solution();
void initial();
int bfs();
private:
char mp[10][10];
int n, m;
int sx,sy,bx,by,ex,ey;
int a[4], b[4];
int visited[10][10][10][10];
};
Solution::Solution(){
a[0] = 0, a[1] = 0, a[2] = 1, a[3] = -1;
b[0] = 1, b[1] = -1, b[2] = 0, b[3] = 0;
memset(visited, 0, sizeof(visited));
}
void Solution::initial(){
cin >> n >> m;
for (int i = 0; i < n; ++i){
for (int j = 0; j < m; ++j){
cin >> mp[i][j];
if (mp[i][j] == '*'){ bx = i, by = j; }
else if (mp[i][j] == 'X')sx = i, sy = j;
else if (mp[i][j] == '@')ex = i, ey = j;
}
}
}
int Solution::bfs(){
visited[sx][sy][bx][by] = 1;
state s(sx,sy,bx,by);
queue<state> que;
que.push(s);
while (que.size()){
state front = que.front();
que.pop();
if (front.xb == ex && front.yb == ey) return visited[front.x][front.y][front.xb][front.yb] - 1;
for (int i = 0; i < 4; ++i){
int nx = front.x + a[i], ny = front.y + b[i];
if (nx<0 || ny<0 || mp[nx][ny] == '#' || nx >= n || ny >= m)continue;
if (nx == front.xb && ny == front.yb){
if (nx + a[i]<0 || ny + b[i]<0 || mp[nx + a[i]][ny + b[i]] == '#' || nx + a[i] >= n || ny + b[i] >= m)continue;
if (visited[nx][ny][nx + a[i]][ny + b[i]]) continue;
visited[nx][ny][nx + a[i]][ny + b[i]] = visited[front.x][front.y][front.xb][front.yb] + 1;
que.push(state(nx,ny,nx+a[i],ny+b[i]));
}else{
if (visited[nx][ny][front.xb][front.yb]) continue;
visited[nx][ny][front.xb][front.yb] = visited[front.x][front.y][front.xb][front.yb] + 1;
que.push(state(nx, ny, front.xb, front.yb));
}
}
}
return -1;
}
int main()
{
Solution obj;
obj.initial();
cout << obj.bfs() << endl;
return 0;
}