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

来源:互联网 发布:常见面试几种算法 编辑:程序博客网 时间:2024/05/22 06:16

推箱子

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&lt;=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
题目分析:
每次推箱子前判断人可达的点,用以判断箱子能否沿某一方向推,两个bfs搞定,在求解的bfs中记录从每个方向到达某点,因为每个点很可能的到达多次,但是从每个方向在获得最优解的情况只会到达一次
 
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <queue>#define MAX 9using 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 ( ) );    }}


0 0