您的位置:首页 > 其它

hdu 1254 推箱子(bfs判断路径可达+bfs搜索最小)

2015-04-25 12:27 453 查看

推箱子

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 5982 Accepted Submission(s): 1704



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




Author
Ignatius.L & weigang Lee
题目分析:

每次推箱子前判断人可达的点,用以判断箱子能否沿某一方向推,两个bfs搞定,在求解的bfs中记录从每个方向到达某点,因为每个点很可能的到达多次,但是从每个方向在获得最优解的情况只会到达一次

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#define MAX 9

using namespace std;

int mp[MAX][MAX];
int mark[MAX][MAX];
int t,n,m,sx,sy,ex,ey,px,py;

struct Node
{
    int x1,y1,x2,y2,t;
};

int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};

void judge ( int x , int y , int x2 , int y2 )
{
    Node a;
    a.x1 = x , a.y1 = y;
    queue<Node> q;
    memset ( mark , 0 , sizeof ( mark ) );
    q.push ( a );
    mark[x][y] = 1;
    while ( !q.empty() )
    {
        Node u = q.front();
        q.pop();
        for ( int i = 0 ; i < 4 ; i++ )
        {
            Node t;
            t.x1 = u.x1 + dx[i];
            t.y1 = u.y1 + dy[i];
            if ( mp[t.x1][t.y1] == 1 || (t.x1 == x2 && t.y1 == y2 ) ) continue;
            if ( mark[t.x1][t.y1] ) continue;
            mark[t.x1][t.y1] = 1;
            q.push ( t );
        }
    }
}

bool used[4][MAX][MAX];

int bfs ( )
{
    memset ( used , 0 , sizeof ( used ) );
    queue<Node> q;
    Node a;
    a.x1 = sx , a.y1 = sy , a.x2 = px , a.y2 = py , a.t = 0;
    q.push ( a );
    while ( !q.empty() )
    {
        Node b = q.front();
        q.pop();
        if ( b.x1 == ex && b.y1 == ey )
            return b.t;
        judge ( b.x2 , b.y2 , b.x1 , b.y1 );
        for ( int i = 0 ; i < 4 ; i++ )
        {
            a.x2 = b.x1 , a.y2 = b.y1;
            a.x1 = b.x1 + dx[i] , a.y1 = b.y1 + dy[i];
            a.t = b.t + 1; 
            if ( mp[a.x1][a.y1] == 1 ) continue;
            if ( used[i][a.x1][a.y1] ) continue;
            if ( !mark[b.x1-dx[i]][b.y1-dy[i]] ) continue;
            used[i][a.x1][a.y1] = 1;
            q.push ( a );
        }
    }
    return -1;
}

int main ( )
{
    scanf ( "%d" , &t );
    while ( t-- )
    {
        scanf ( "%d%d" , &n , &m );
        for ( int i = 0 ; i < MAX ; i++ )
            for ( int j = 0 ; j < MAX ; j++ )
                mp[i][j] = 1;
        for ( int i = 1 ; i <= n ; i++ )
            for ( int j = 1 ; j <= m ; j++ )
            {
                scanf ( "%d" , &mp[i][j] );
                if ( mp[i][j] == 3 ) ex = i , ey = j;
                if ( mp[i][j] == 4 ) px = i , py = j;
                if ( mp[i][j] == 2 ) sx = i , sy = j;
            }
        printf ( "%d\n" , bfs ( ) );
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: