#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL __int64
const int INF=1e8;
const int maxn=10;
int dir[4][2]={{1,0},{0,1},{0,-1},{-1,0}};
int n,m;
struct node{
int x,y;
};
struct node2{
int x,y,xx,yy,step;//x,y是人所在位置,xx,yy为箱子所在位置
};
int e[maxn][maxn],vis[maxn][maxn],x3,y3,mark[maxn][maxn][5];
int bfs(int x1,int y1,int x2,int y2,int x,int y)//判断人能否到达箱子前进方向的后方,即能否推箱子
{
queue<node>qq;
node ff,gg;
int i,j,k,xx,yy;
memset(vis,0,sizeof(vis));
ff.x=x1;ff.y=y1;
vis[x1][y1]=1;
qq.push(ff);
while(!qq.empty())
{
ff=qq.front();
qq.pop();
if(ff.x==x2&&ff.y==y2)
{
while(!qq.empty())
qq.pop();
return 1;
}
for(i=0;i<4;i++)
{
xx=ff.x+dir[i][0];
yy=ff.y+dir[i][1];
if(xx==x&&yy==y)continue;//箱子也是不能穿过的
if(xx<0||yy<0||xx>=n||yy>=m||e[xx][yy]==1||vis[xx][yy]==1)continue;
gg.x=xx;gg.y=yy;
vis[xx][yy]=1;
qq.push(gg);
}
}
return 0;
}
void bfs2(int x1,int y1,int x2,int y2)//推箱子
{
queue<node2>q;
node2 f,g;
int i,j,xx,yy,xxx,yyy;
f.x=x1;f.y=y1;f.xx=x2;f.yy=y2;f.step=0;
q.push(f);
while(!q.empty())
{
f=q.front();
q.pop();
if(f.xx==x3&&f.yy==y3){printf("%d\n",f.step);while(!q.empty())q.pop();return;}
for(i=0;i<4;i++)
{
xx=f.xx+dir[i][0];
yy=f.yy+dir[i][1];
xxx=f.xx-dir[i][0];
yyy=f.yy-dir[i][1];
if(xx<0||yy<0||xx>=n||yy>=m||xxx<0||yyy<0||xxx>=n||yyy>=m)continue;
if(e[xx][yy]==1||e[xxx][yyy]==1||mark[xx][yy][i])continue;
if(!bfs(f.x,f.y,xxx,yyy,f.xx,f.yy))continue;
g.x=f.xx;g.y=f.yy;
g.xx=xx;g.yy=yy;g.step=f.step+1;
mark[xx][yy][i]=1;
q.push(g);
}
}
printf("-1\n");
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int i,j,k,x1,y1,x2,y2;
x3=y3=-1;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
scanf("%d",&e[i][j]);
if(e[i][j]==3){x3=i;y3=j;}
if(e[i][j]==4){x1=i;y1=j;}
if(e[i][j]==2){x2=i;y2=j;}
}
memset(mark,0,sizeof(mark));
bfs2(x1,y1,x2,y2);
}
return 0;
}
/*
推箱子,每次箱子进一个都要更新人的位置,还要判断人是否能到箱子前进方向的后方,不然不能推。两个bfs解决。
这里的难点就是箱子可能往回走,详细见特例。所以直接标记位置是不可以的,还要标记推过了的方向,所以要三维数组标记。(我在这背坑个半死。。)
特例:
4 3
0 0 0
0 0 1
0 2 3
1 4 1
6 3
0 0 0
0 0 0
1 0 0
0 0 1
0 2 3
1 4 1
*/
hdu 1254 推箱子 双层bfs
最新推荐文章于 2021-11-25 09:29:38 发布