hdu 1732 Push Box (bfs)

题意:推箱子升级版,将三个箱子推到三个洞里,求最小步骤

分析:思路不难,就是处理起来,细节太多,纠结死了。一个八维的布尔数组判重,差点就MLE了

View Code
#include <iostream>
#include <algorithm>
#include <queue>
#define size 9
using namespace std;
struct Node
{
int x, y;
int Box[3][2];//记录三个箱子的位置
int step;
char map[size][size];
} start;
int dir[4][2] = {{0, -1}, {0, 1}, { -1, 0}, {1, 0}};
char map[size][size];
int n, m;
int T_map[size][size];//临时地图
bool visit[size][size][size][size][size][size][size][size];//八维数组,状态判重
Node pre, nex;
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(visit, false, sizeof(visit));
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 + dir[i][0];
int yy = Tpre.y + dir[i][1];
//判断是否入队
if (check(xx, yy) && Tmap[xx][yy] != '#' && !(visit[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 + dir[i][0];
int by = yy + dir[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 ((visit[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;
}
nex.x = xx, nex.y = yy;
for (int ii = 0; ii < 3; ii ++)
{
nex.Box[ii][0] = Tpre.Box[ii][0];
nex.Box[ii][1] = Tpre.Box[ii][1];
}
//入队
nex.step = Tpre.step + 1;
visit[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(nex.map, Tmap, sizeof(nex.map));
Que.push(nex);
}
}
}
}
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;
}

 

posted @ 2012-02-23 10:10  枕边梦  阅读(365)  评论(0编辑  收藏  举报