Total Submission(s): 5982 Accepted Submission(s): 1704
现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格.
每次推箱子前判断人可达的点,用以判断箱子能否沿某一方向推,两个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 ( ) );
}
}