题目来源:牛客网
[编程题] 推箱子
大家一定玩过“推箱子”这个经典的游戏。具体规则就是在一个N*M的地图上,有1个玩家、1个箱子、1个目的地以及若干障碍,其余是空地。玩家可以往上下左右4个方向移动,但是不能移动出地图或者移动到障碍里去。如果往这个方向移动推到了箱子,箱子也会按这个方向移动一格,当然,箱子也不能被推出地图或推到障碍里。当箱子被推到目的地以后,游戏目标达成。现在告诉你游戏开始是初始的地图布局,请你求出玩家最少需要移动多少步才能够将游戏目标达成。
输入描述:
每个测试输入包含1个测试用例
第一行输入两个数字N,M表示地图的大小。其中0
每个地图必定包含1个玩家、1个箱子、1个目的地。
输出描述:
输出一个数字表示玩家最少需要移动多少步才能将游戏目标达成。当无论如何达成不了的时候,输出-1。
输入例子:
4 4
....
..*@
....
.X..
6 6
...#..
......
#*##..
..##.#
..X...
.@#...
输出例子:
3
11
*/
#include
#include
using namespace std;
struct pt
{
int x;
int y;
};
struct pos
{
pt ppos;
pt bpos;
};
bool map[8][8];
int status[8][8][8][8];
pt dst, person, box;
int minlength;
void dfs(int row, int col)
{
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
for (int m = 0; m < 8; m++)
for (int n = 0; n < 8; n++)
{
status[i][j][m][n] = -1;
}
status[person.x][person.y][box.x][box.y] = 0;
queue slist;
pos start = { person, box };
slist.push(start);
while (!slist.empty())
{
pos cur = slist.front();
slist.pop();
int px = cur.ppos.x;
int py = cur.ppos.y;
int bx = cur.bpos.x;
int by = cur.bpos.y;
int len = status[px][py][bx][by];
if (bx == dst.x && by == dst.y)
{
minlength = len;
return;
}
else
{
//上
if ((px - 1) >= 0 && map[px - 1][py])
{
pt ppos = { px - 1, py };
if ((px - 1) == bx && py == by)
{
if ((bx - 1) >= 0 && map[bx - 1][by] && status[px - 1][py][bx - 1][by] == -1)
{
status[px - 1][py][bx - 1][by] = len + 1;
pt bpos = { bx - 1, by };
pos newpos = { ppos, bpos };
slist.push(newpos);
}
}
else if (status[px - 1][py][bx][by] == -1)
{
status[px - 1][py][bx][by] = len + 1;
pos newpos = { ppos, cur.bpos };
slist.push(newpos);
}
}
//下
if ((px + 1) < row && map[px + 1][py])
{
pt ppos = { px + 1, py };
if ((px + 1) == bx && py == by)
{
if ((bx + 1) < row && map[bx + 1][by] && status[px + 1][py][bx + 1][by] == -1)
{
status[px + 1][py][bx + 1][by] = len + 1;
pt bpos = { bx + 1, by };
pos newpos = { ppos, bpos };
slist.push(newpos);
}
}
else if (status[px + 1][py][bx][by] == -1)
{
status[px + 1][py][bx][by] = len + 1;
pos newpos = { ppos, cur.bpos };
slist.push(newpos);
}
}
//左
if ((py - 1) >= 0 && map[px][py - 1])
{
pt ppos = { px, py - 1 };
if (px == bx && (py - 1) == by)
{
if ((by - 1) >= 0 && map[bx][by - 1] && status[px][py - 1][bx][by - 1] == -1)
{
status[px][py - 1][bx][by - 1] = len + 1;
pt bpos = { bx, by - 1 };
pos newpos = { ppos, bpos };
slist.push(newpos);
}
}
else if (status[px][py - 1][bx][by] == -1)
{
status[px][py - 1][bx][by] = len + 1;
pos newpos = { ppos, cur.bpos };
slist.push(newpos);
}
}
//右
if ((py + 1) < col && map[px][py + 1])
{
pt ppos = { px, py + 1 };
if (px == bx && (py + 1) == by)
{
if ((by + 1) < col && map[bx][by + 1] && status[px][py + 1][bx][by + 1] == -1)
{
status[px][py + 1][bx][by + 1] = len + 1;
pt bpos = { bx, by + 1 };
pos newpos = { ppos, bpos };
slist.push(newpos);
}
}
else if (status[px][py + 1][bx][by] == -1)
{
status[px][py + 1][bx][by] = len + 1;
pos newpos = { ppos, cur.bpos };
slist.push(newpos);
}
}
}
}
minlength = -1;
}
int main(void)
{
int row, col;
cin >> row >> col;
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
{
char a;
cin >> a;
do
{
cin >> a;
} while (a == ' ');
switch (a)
{
case '.':map[i][j] = true; break;
case 'X':
map[i][j] = true;
person.x = i; person.y = j;
break;
case '*':
map[i][j] = true;
box.x = i; box.y = j;
break;
case '#':
map[i][j] = false;
break;
case '@':
map[i][j] = true;
dst.x = i; dst.y = j;
break;
}
}
//输入完毕,开始搜索
dfs(row, col);
cout << minlength;
cin.get();
cin.get();
return 0;
}