ACM 搜索 HDU 1254 推箱子

来源:互联网 发布:生产管理erp源码 编辑:程序博客网 时间:2024/06/10 21:53

Problem Description
推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个角上(如图2)那么箱子就不能再被移动了,如果箱子被推到一面墙上,那么箱子只能沿着墙移动.

现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格.


 

Input
输入数据的第一行是一个整数T(1<=T<=20),代表测试数据的数量.然后是T组测试数据,每组测试数据的第一行是两个正整数M,N(2<=M,N<=7),代表房间的大小,然后是一个M行N列的矩阵,代表房间的布局,其中0代表空的地板,1代表墙,2代表箱子的起始位置,3代表箱子要被推去的位置,4代表搬运工的起始位置.
 

Output
对于每组测试数据,输出搬运工最少需要推动箱子多少格才能帮箱子推到指定位置,如果不能推到指定位置则输出-1.
 

Sample Input
15 50 3 0 0 01 0 1 4 00 0 1 0 01 0 2 0 00 0 0 0 0
 

Sample Output
4
 

Author
Ignatius.L & weigang Lee


#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] != 1return 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, 0sizeof(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, 0sizeof(hash));
    memset(maze, 0sizeof(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;
}
0 0
原创粉丝点击