Hdu 1254 推箱子

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


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

Hdu 1254 推箱子

 

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

 

 

你可能感兴趣的:(HDU)