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


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

 

思路:很简单的状态搜索题,大概就是对箱子采用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] != 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;
}

 

 

posted on 2012-09-20 19:23  有间博客  阅读(1180)  评论(0编辑  收藏  举报