箱子每走一步,需要bfs搜索人是否能走到推箱子的位置。箱子可以走已经走过的位置,但不能在已经走过的位置走相同的方向,需要用mark[x][y][dir]三维数组标记。
#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
int m,n;
int map[10][10]; //地图
int mark[10][10][4]; //注意:箱子可以走已经走过的位置,
//但在已经走过的位置 ,不能走之前走过的方向
class step
{
public:
int b_x,b_y; //箱子当前的x坐标,y坐标
int p_x,p_y; // 人当前的x坐标,y坐标
int steps; //行走的步数
step(int b1,int b2,int p1,int p2,int s):b_x(b1),
b_y(b2),p_x(p1),p_y(p2),steps(s){}
step(){}
};
class people
{
public:
int x,y;
people(int x_,int y_):x(x_),y(y_){
}
people(){
}
};
int x_change[4]={1,-1,0,0};
int y_change[4]={0,0,1,-1};
bool people_bfs(int p_x,int p_y,int pn_x,int pn_y,int b_x,int b_y)
{ //参数分别是人当前的x坐标,y坐标,人需要走到的x坐标,y坐标
//箱子的x坐标,y坐标(不能走箱子所在的位置)
int mark2[10][10];
memset(mark2,0,sizeof(mark2));
queue<people> aqueue;
aqueue.push(people(p_x,p_y));
mark2[p_x][p_y]=1;
while(!aqueue.empty())
{
people p1=aqueue.front();
aqueue.pop();
if(p1.x==pn_x&&p1.y==pn_y) //可以走到返回真
{
return true;
}
for(int i=0;i<4;i++)
{
int x_t = p1.x+x_change[i];
int y_t = p1.y+y_change[i];
if(x_t==b_x && y_t==b_y)
continue;
if(x_t>=1 && y_t>=1 && x_t<=m && y_t<=n
&& !mark2[x_t][y_t] && map[x_t][y_t]!=1 )
{
mark2[x_t][y_t]=1;
aqueue.push(people(x_t,y_t));
}
}
}
return false;
}
int main()
{
int t;
cin>>t;
while(t--)
{
int box_x,box_y;
int people_x,people_y;
memset(map,0,sizeof(map));
memset(mark,0,sizeof(mark));
cin>>m>>n;
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
cin>>map[i][j];
if(map[i][j]==2)
{
box_x=i;
box_y=j;
}
else if(map[i][j]==4)
{
people_x=i;
people_y=j;
}
}
}
queue<step> aqueue;
aqueue.push(step(box_x,box_y,people_x,people_y,0));
int flag=0;
while(!aqueue.empty())
{
step s1 = aqueue.front();
aqueue.pop();
//cout<<s1.b_x<<" "<<s1.b_y<<" "<<s1.p_x<<" "<<s1.p_y<<" "<<s1.steps<<endl;
if(map[s1.b_x][s1.b_y]==3)
{
flag=s1.steps;
break;
}
if( (s1.b_x==1&&s1.b_y==1) || (s1.b_x==1&&s1.b_y==n)
||(s1.b_x==m&&s1.b_y==1)||(s1.b_x==m&&s1.b_y==n) )
{
continue;
}
for(int k=0;k<4;k++)
{
int x_t = s1.b_x + x_change[k];
int y_t = s1.b_y + y_change[k];
if(x_t>=1 && y_t>=1 && x_t<=m && y_t<=n
&& map[x_t][y_t]!=1 && !mark[s1.b_x][s1.b_y][k]
&& people_bfs(s1.p_x,s1.p_y, s1.b_x - x_change[k],s1.b_y - y_change[k],s1.b_x,s1.b_y ) )
{
mark[s1.b_x][s1.b_y][k]=1;
aqueue.push(step(x_t,y_t,s1.b_x,s1.b_y,s1.steps+1));
}
}
}
if(flag)
cout<<flag<<endl;
else
cout<<"-1"<<endl;
}
return 0;
}