Push Box
来源:互联网 发布:装饰美工职业资格证书 编辑:程序博客网 时间:2024/05/18 03:02
Push Box
Problem DescriptionPush Box is a classic puzzle game. This game play in a grid, there are five types of block in it, the player, the box, the hole, empty place, and the wall. In every step, player can move up, down, left, or right, if the target place is empty. Moreover, if a box in the target place, and the next place in that direction is empty, player can move to the target place, and then push the box to the next place. Remember, both of the player and boxes can't move out of the grid, or you may assume that there is a wall suround the whole grid. The objective of this game is to push every box to a hole. Now, your problem is to find the strategy to achieve the goal with shortest steps, supposed there are exactly three boxes.
InputThe input consists of several test cases. Each test case start with a line containing two number, n, m(1 < n, m ≤ 8), the rows and the columns of grid. Then n lines follow, each contain exact m characters, representing the type of block in it. (for empty place, X for player, * for box, # for wall, @ for hole). Each case contain exactly one X, three *, and three @. The input end with EOF.
OutputYou have to print the length of shortest strategy in a single line for each case. (-1 if no such strategy)
Sample Input4 4......*@..*@.X*@6 6...#@.@..*..#*##....##*#..X....@#...
Sample Output711
4 4......*@..*@.X*@6 6...#@.@..*..#*##....##*#..X....@#...
711
#include <iostream>
#include <queue>
using namespace std;
const int size = 9 ;
struct Node
{
int x, y;
int Box[3][2];//记录三个箱子的位置
int step;
char map[size][size];
}start;
const int Go[4][2] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};
char map[size][size];
int n, m;
int T_map[size][size];//临时地图
bool visited[size][size][size][size][size][size][size][size];//八维数组,状态判重
Node pre, next;
bool is_finish(Node a)//判断是否每个箱子都入洞
{
return (map[a.Box[0][0]][a.Box[0][1]] == '@' && map[a.Box[1][0]][a.Box[1][1]] == '@' && map[a.Box[2][0]][a.Box[2][1]] == '@' );
}
bool check(int x, int y)
{
return (x >= 0 && x < n && y >= 0 && y < m);
}
int ans;
char Tmap[size][size];//临时地图
void Bfs()
{
queue <Node> Que;
memset(visited, false, sizeof(visited));
Que.push(start);
while (!Que.empty()){
pre = Que.front();
Que.pop();
if (is_finish(pre)){
ans = pre.step;
return ;
}
for (int i = 0; i < 4; i ++){
//将前一个的地图copy到临时地图中
memcpy(Tmap, pre.map, sizeof(Tmap));
Node Tpre = pre;
int xx = Tpre.x + Go[i][0];
int yy = Tpre.y + Go[i][1];
//判断是否入队
if (check(xx, yy) && Tmap[xx][yy] != '#' && !(visited[xx][yy][Tpre.Box[0][0]][Tpre.Box[0][1]][Tpre.Box[1][0]][Tpre.Box[1][1]][Tpre.Box[2][0]][Tpre.Box[2][1]])){
//如果下一个点为箱子的话
if (Tmap[xx][yy] == '*'){
int bx = xx + Go[i][0];
int by = yy + Go[i][1];
//判断箱子能否被推动
if (check(bx, by) && Tmap[bx][by] != '#' && Tmap[bx][by] != '*'){
int ii = 0;
//查找推动的是哪个箱子
for (ii = 0; ii < 3; ii ++){
if (Tpre.Box[ii][1] == yy && Tpre.Box[ii][0] == xx){
break;
}
}
//推动后临时地图该点变为'*'
Tmap[bx][by] = '*';
//原来的两个点都变成'.'
Tmap[pre.x][pre.y] = '.';
Tmap[xx][yy] = '.';
//如果前一个点是'@'(洞)的话
if (T_map[pre.x][pre.y]){
Tmap[pre.x][pre.y] = '@';
}
if (T_map[xx][yy]){
Tmap[xx][yy] = '@';
}
Tpre.Box[ii][1] = by, Tpre.Box[ii][0] = bx;
Tpre.x = xx, Tpre.y = yy;
if ((visited[xx][yy][Tpre.Box[0][0]][Tpre.Box[0][1]][Tpre.Box[1][0]][Tpre.Box[1][1]][Tpre.Box[2][0]][Tpre.Box[2][1]]))continue;
}
else continue;
}
next.x = xx, next.y = yy;
for (int ii = 0; ii < 3; ii ++){
next.Box[ii][0] = Tpre.Box[ii][0];
next.Box[ii][1] = Tpre.Box[ii][1];
}
//入队
next.step = Tpre.step + 1;
visited[xx][yy][Tpre.Box[0][0]][Tpre.Box[0][1]][Tpre.Box[1][0]][Tpre.Box[1][1]][Tpre.Box[2][0]][Tpre.Box[2][1]] = true;
memcpy(next.map, Tmap, sizeof(next.map));
Que.push(next);
}
}
}
}
int main()
{
while (scanf("%d%d", &n, &m) != EOF){
memset(T_map, 0, sizeof(T_map));
ans = -1;
int numB = 0;
for (int i = 0; i < n; i ++){
scanf("%s", map[i]);
for (int j = 0; j < m; j ++){
if (map[i][j] == 'X'){//记录起点
start.x = i, start. y = j;
start.step = 0;
map[i][j] = '.';
}
if (map[i][j] == '*'){//记录箱子
start.Box[numB][0] = i, start.Box[numB ++][1] = j;
}
if (map[i][j] == '@'){//记录洞
T_map[i][j] = 1;
}
}
}
memcpy(start.map, map, sizeof(start.map));
Bfs();
printf("%d\n", ans);
}
return 0;
}
#include <queue>
using namespace std;
const int size = 9 ;
struct Node
{
int x, y;
int Box[3][2];//记录三个箱子的位置
int step;
char map[size][size];
}start;
const int Go[4][2] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};
char map[size][size];
int n, m;
int T_map[size][size];//临时地图
bool visited[size][size][size][size][size][size][size][size];//八维数组,状态判重
Node pre, next;
bool is_finish(Node a)//判断是否每个箱子都入洞
{
return (map[a.Box[0][0]][a.Box[0][1]] == '@' && map[a.Box[1][0]][a.Box[1][1]] == '@' && map[a.Box[2][0]][a.Box[2][1]] == '@' );
}
bool check(int x, int y)
{
return (x >= 0 && x < n && y >= 0 && y < m);
}
int ans;
char Tmap[size][size];//临时地图
void Bfs()
{
queue <Node> Que;
memset(visited, false, sizeof(visited));
Que.push(start);
while (!Que.empty()){
pre = Que.front();
Que.pop();
if (is_finish(pre)){
ans = pre.step;
return ;
}
for (int i = 0; i < 4; i ++){
//将前一个的地图copy到临时地图中
memcpy(Tmap, pre.map, sizeof(Tmap));
Node Tpre = pre;
int xx = Tpre.x + Go[i][0];
int yy = Tpre.y + Go[i][1];
//判断是否入队
if (check(xx, yy) && Tmap[xx][yy] != '#' && !(visited[xx][yy][Tpre.Box[0][0]][Tpre.Box[0][1]][Tpre.Box[1][0]][Tpre.Box[1][1]][Tpre.Box[2][0]][Tpre.Box[2][1]])){
//如果下一个点为箱子的话
if (Tmap[xx][yy] == '*'){
int bx = xx + Go[i][0];
int by = yy + Go[i][1];
//判断箱子能否被推动
if (check(bx, by) && Tmap[bx][by] != '#' && Tmap[bx][by] != '*'){
int ii = 0;
//查找推动的是哪个箱子
for (ii = 0; ii < 3; ii ++){
if (Tpre.Box[ii][1] == yy && Tpre.Box[ii][0] == xx){
break;
}
}
//推动后临时地图该点变为'*'
Tmap[bx][by] = '*';
//原来的两个点都变成'.'
Tmap[pre.x][pre.y] = '.';
Tmap[xx][yy] = '.';
//如果前一个点是'@'(洞)的话
if (T_map[pre.x][pre.y]){
Tmap[pre.x][pre.y] = '@';
}
if (T_map[xx][yy]){
Tmap[xx][yy] = '@';
}
Tpre.Box[ii][1] = by, Tpre.Box[ii][0] = bx;
Tpre.x = xx, Tpre.y = yy;
if ((visited[xx][yy][Tpre.Box[0][0]][Tpre.Box[0][1]][Tpre.Box[1][0]][Tpre.Box[1][1]][Tpre.Box[2][0]][Tpre.Box[2][1]]))continue;
}
else continue;
}
next.x = xx, next.y = yy;
for (int ii = 0; ii < 3; ii ++){
next.Box[ii][0] = Tpre.Box[ii][0];
next.Box[ii][1] = Tpre.Box[ii][1];
}
//入队
next.step = Tpre.step + 1;
visited[xx][yy][Tpre.Box[0][0]][Tpre.Box[0][1]][Tpre.Box[1][0]][Tpre.Box[1][1]][Tpre.Box[2][0]][Tpre.Box[2][1]] = true;
memcpy(next.map, Tmap, sizeof(next.map));
Que.push(next);
}
}
}
}
int main()
{
while (scanf("%d%d", &n, &m) != EOF){
memset(T_map, 0, sizeof(T_map));
ans = -1;
int numB = 0;
for (int i = 0; i < n; i ++){
scanf("%s", map[i]);
for (int j = 0; j < m; j ++){
if (map[i][j] == 'X'){//记录起点
start.x = i, start. y = j;
start.step = 0;
map[i][j] = '.';
}
if (map[i][j] == '*'){//记录箱子
start.Box[numB][0] = i, start.Box[numB ++][1] = j;
}
if (map[i][j] == '@'){//记录洞
T_map[i][j] = 1;
}
}
}
memcpy(start.map, map, sizeof(start.map));
Bfs();
printf("%d\n", ans);
}
return 0;
}
- Push Box
- Push Box
- HDU 1732 push Box
- HDU Push Box
- HDU 1732 Push Box
- hdu1732 Push Box (bfs)
- hdu1732 Push Box ---- BFS
- hdu1732 Push Box【搜索】
- Push Box (BFS)
- Push Box(推箱子)
- HDU 1732 Push Box(搜索)
- 杭电 1732 Push Box
- hdu 1732 Push Box(BFS)
- HDU---1732 Push Box【BFS】
- bfs hdu 1732 push the box
- HDU 1732 Push Box(搜索)
- HDU-1732 Push Box BFS + BFS
- hdu 1732 Push Box(bfs)
- poj2186 强连通+缩点 如果让我说:我只能说,实力决定一切
- [python]subprocess调用外部命令屏蔽输出
- Android开发之XML解析——SAX解析XML
- 使用pthread实现统计直方图
- SVN服务器搭建和使用
- Push Box
- 黑马程序员——JAVA学习日志10
- 自定义std::sort的比较函数时发生"invalid operator<"错误原因
- android 编译过程及错误处理
- 面对挑战,----让暴风雨来得更猛烈些吧
- spring结合quartz的定时的2种方式
- tcp滑动窗口协议——《TCP/IP详解,卷1:协议》
- matlab绘图
- SVN服务器搭配说明