HDU 1254(推箱子)

推箱子

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3313    Accepted Submission(s): 898

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
1 5 5 0 3 0 0 0 1 0 1 4 0 0 0 1 0 0 1 0 2 0 0 0 0 0 0 0
 
Sample Output
4
 
/*BFS中等偏简单
Author: shaorui
Date: 2012/10/5
此题要注意的是:
1,人能不能走到能推箱子的位置
2,人不能穿过箱子
3,箱子走过的地方还可能再经过(箱子在一个地方走的方向可能不同,所以需一个三维数组标记visited[][][])
BFS1()判断人能不能到能推箱子的位置
BFS2()输出至少要推的箱子数(若没有就输出-1)
*/
#include<iostream>
#include<queue>
using namespace std;
#define maxn 8
int maze[maxn][maxn];
bool visited[maxn][maxn][4]; //标记箱子
bool visited1[maxn][maxn];   //标记人
int si,sj,ei,ej,pi,pj,m,n;
int dir[][2] = {{0,-1},{1,0},{0,1},{-1,0}}; 
struct node
{
    int x,y,t,px,py;  //x,y为箱子的位置,px,py为人的位置
};
bool ok(int i,int j)
{
    return i >= 1 && i <= m && j >= 1 && j <= n && maze[i][j] != 1;
}
bool BFS1(int px,int py,int sx,int sy,int bx,int by)//px,py为人的起始位置,sx,sy为与箱子相邻的地方(人要到这个位置推箱子),bx,by为箱子的位置
{
    if(px == sx && py == sy)    //注意这个,因为这个wa了n次
         return true;
    queue<node> que;
    memset(visited1,false,sizeof(visited1));
    node p,q;
    p.x = px,p.y = py;
    que.push(p);
    visited1[px][py] = true;
    while(!que.empty())
    {
        p = que.front();
        que.pop();
        for(int i = 0; i < 4; i++)
        {
            q.x = p.x+dir[i][0],q.y = p.y+dir[i][1];
            if(q.x == sx && q.y == sy)
                return true;
            if(ok(q.x,q.y) && !visited1[q.x][q.y] && (q.x != bx || q.y != by))
                que.push(q),visited1[q.x][q.y] = true;
        }
    }
    return false;
}
void BFS2()
{
    queue<node> que;
    memset(visited,false,sizeof(visited));
    node p,q;
    p.x = si,p.y = sj,p.t = 0,p.px = pi,p.py = pj;
    que.push(p);
    while(!que.empty())
    {
        p = que.front();
        que.pop();
        if(p.x == ei && p.y == ej)
        {
            printf("%d\n",p.t);
            return;
        }
        for(int i = 0; i < 4; i++)
        {
            q.x = p.x+dir[i][0],q.y = p.y+dir[i][1],q.t = p.t+1,q.px = p.x,q.py = p.y;
            if(ok(p.x-dir[i][0],p.y-dir[i][1]) && (BFS1(p.px,p.py,p.x-dir[i][0],p.y-dir[i][1],p.x,p.y)) && ok(q.x,q.y) && !visited[q.x][q.y][i])
                que.push(q),visited[q.x][q.y][i] = true;
        }
    }
    printf("-1\n");
}
int main()
{
    //freopen("1009.txt","r",stdin);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int i,j;
        scanf("%d%d",&m,&n);
        for(i = 1; i <= m; i++)
            for(j = 1; j <= n; j++)
            {
                scanf("%d",&maze[i][j]);
                if(maze[i][j] == 2)
                    si = i,sj = j;
                if(maze[i][j] == 3)
                    ei = i,ej = j;
                if(maze[i][j] == 4)
                    pi = i,pj = j;
            }
            BFS2();
    }
    return 0;
}

 

posted @ 2012-10-05 13:28  sorryhao  阅读(360)  评论(0)    收藏  举报