您的位置:首页 > 其它

Hdu 1254 推箱子

2012-09-20 19:23 337 查看
大意:现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格。

(搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个角上(如图)那么箱子就不能再被移动了,如果箱子被推到一面墙上,那么箱子只能沿着墙移动。)



思路:很简单的状态搜索题,大概就是对箱子采用BFS的思想,然后判断人是否可以走到箱子的对面(DFS/BFS),由于数据大,可以用四重标记数组来标记(hash[M][M][M][M])不过有许多细节需要注意。

(1)采用DFS/BFS判断人是否可以到达箱子的对面时,要明确人不能穿过箱子,即对箱子标记flag[p.Bx][p.By] = 1;

(2)求箱子的对面求坐标时要保证这个坐标没有超边界。

(3)DFS时不需要回溯。

(4)推箱子时,人的位置不会跟随箱子的移动而移动。

CODE:

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <queue>
using namespace std;

const int M = 8;
const int dx[] = {-1,1,0,0};
const int dy[] = {0,0,-1,1};
int maze[M][M];

int n, m;

int Bx, By, Mx, My;
int Nx, Ny;
int flag[M][M], hash[M][M][M][M];
int Found;

struct node
{
int Bx, By;
int Mx, My;
int step;
};

int check(int x, int y)
{
if(x >= 0 && x < n && y >= 0 && y < m && maze[x][y] != 1) return 1;
return 0;
}

void dfs(int Nx, int Ny, int Mx, int My)
{
if(Nx == Mx && Ny == My)
{
Found = 1;
return ;
}
for(int i = 0; i < 4 && !Found; i++)
{
int x = Nx + dx[i];
int y = Ny + dy[i];
if(check(x, y) && !flag[x][y])
{
flag[x][y] = 1;
dfs(x, y, Mx, My);
//flag[x][y] = 0; 只需要知道是否可以到达,而不需要回溯,否则TLE。
}
}
}

void bfs(int Bx, int By, int Mx, int My)
{
queue<node> Q;
node p, q;
p.Bx = Bx, p.By = By, p.Mx = Mx, p.My = My, p.step = 0;
Q.push(p);
while(!Q.empty())
{
p = Q.front(); Q.pop();
if(maze[p.Bx][p.By] == 3)
{
printf("%d\n", p.step);
return ;
}
for(int i = 0; i < 4; i++)
{
q = p;
q.Bx += dx[i];
q.By += dy[i];
Nx = p.Bx-dx[i];
Ny = p.By-dy[i]; //箱子对面的坐标
if(check(q.Bx, q.By)&& check(Nx, Ny) && !hash[q.Bx][q.By][Nx][Ny]) //check(Nx, Ny)
{
memset(flag, 0, sizeof(flag));
flag[p.Bx][p.By] = flag[Nx][Ny] = 1; //标记起点与箱子,确保人不能走过。
Found = 0;
dfs(Nx, Ny, p.Mx, p.My);
if(Found)
{
hash[q.Bx][q.By][Nx][Ny] = 1;
q.Mx = Nx, q.My = Ny;
q.step++;
Q.push(q);
}
}
}
}
printf("-1\n");
return ;
}

void init()
{
memset(hash, 0, sizeof(hash));
memset(maze, 0, sizeof(maze));
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
scanf("%d", &maze[i][j]);
if(maze[i][j] == 2)
{
Bx = i;
By = j;
}
if(maze[i][j] == 4)
{
Mx = i;
My = j;
}
}
}
}

int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
init();
bfs(Bx, By, Mx, My);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: