题目大意是在说给一张图,给定人的起点和终点,以及箱子的起始位置,问最少箱子推多少格可以到达终点。
感觉自己的做法稍微有点麻烦了。
先是使用五维的数组pushdir[a][b][c][d][i]表示人在(a,b)位置,箱子在(c,d)位置是否能往上下左右四个方向推动。例如人在(0,0),箱子在(3,5)可以往上下左右四个方向推那么pushdir[0][0][3][5][0]=pushdir[0][0][3][5][1]=pushdir[0][0][3][5][2]=pushdir[0][0][3][5][3]=1同理用0表示该方向不能推。
那么只需要给定图中的障碍物的位置既可以把所有的上面的状态处理出来,再根据题目给的箱子的位置,人的起点位置,终点位置。既可以搜索出答案。
虽然这种解法并不是最简短的。但是是最全面的的。而且非常考验自己的代码能力(最后一个小时一直在打,连手都抖起来了)
不过比赛的时候还是追求效率吧。
贴上代码
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define LL long long
struct node
{
int x,y;
node() {};
node(int xx,int yy)
{
this->x=xx;
this->y=yy;
};
};
struct node1
{
int x,y,xx,yy;
int dep;
node1() {};
node1(int x,int y,int xx,int yy,int dep)
{
this->x=x;
this->y=y;
this->xx=xx;
this->yy=yy;
this->dep=dep;
};
};
int n,m,t,stx,sty,boxx,boxy,edx,edy;
int lastans;
int G[10][10],vis[10][10];
int ansvis[10][10][10][10];
int pushdir[10][10][10][10][4];
int dx[]= {1,-1,0,0}; //down up right left
int dy[]= {0,0,1,-1};
int ddx[]= {-1,1,0,0}; //down up right left
int ddy[]= {0,0,-1,1};
queue<node>q;
void bfs(int i,int j)
{
while(!q.empty())q.pop();
q.push(node(i,j));
vis[i][j]=2;
node temp;
while(!q.empty())
{
temp=q.front();
//cout<<temp.x<<" "<<temp.y<<endl;
q.pop();
for(int k=0; k<4; k++)
{
int newx,newy;
newx=temp.x+dx[k];
newy=temp.y+dy[k];
if(newx<n&&newx>=0&&newy<m&&newy>=0&&vis[newx][newy]!=1&&vis[newx][newy]!=2)
{
q.push(node(newx,newy));
vis[newx][newy]=2;
}
}
}
return ;
}
queue<node1>qq;
void bfsans()
{
while(!qq.empty())qq.pop();
qq.push(node1(stx,sty,boxx,boxy,0));
ansvis[stx][sty][boxx][boxy]=1;
node1 temp;
while(!qq.empty())
{
temp=qq.front();
if(temp.xx==edx&&temp.yy==edy)
{
lastans=min(lastans,temp.dep);
}
qq.pop();
for(int i=0; i<4; i++)
{
int newx,newy;
newx=temp.xx+ddx[i];
newy=temp.yy+ddy[i];
if(newx<n && newx>=0 && newy<m && newy>=0 && ansvis[temp.xx][temp.yy][newx][newy]==0&&pushdir[temp.x][temp.y][temp.xx][temp.yy][i])
{
qq.push(node1(temp.xx,temp.yy,newx,newy,temp.dep+1));
ansvis[temp.xx][temp.yy][newx][newy]=1;
}
}
}
}
int main()
{
cin>>t;
while(t--)
{
memset(pushdir,0,sizeof(pushdir));
memset(vis,0,sizeof(vis));
cin>>n>>m;
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
cin>>G[i][j];
if(G[i][j]==4)
{
stx=i;
sty=j;
G[i][j]=0;
}
if(G[i][j]==3)
{
edx=i;
edy=j;
G[i][j]=0;
}
if(G[i][j]==2)
{
boxx=i;
boxy=j;
G[i][j]=0;
}
}
}
for(int i=0; i<n; i++) //people
{
for(int j=0; j<m; j++)
{
for(int ii=0; ii<n; ii++) //box
{
for(int jj=0; jj<m; jj++)
{
memcpy(vis,G,sizeof(vis));
if(i==ii&&j==jj||vis[ii][jj]==1||vis[i][j]==1)continue;
vis[ii][jj]=1;
bfs(i,j);
for(int k=0; k<4; k++)
{
int newx,newy,nnewx,nnewy;
newx=ii+dx[k];
newy=jj+dy[k];
nnewx=ii+ddx[k];
nnewy=jj+ddy[k];
if(newx<n && newx>=0 && newy<m && newy>=0 && vis[newx][newy]==2&&
nnewx<n && nnewx>=0 && nnewy<m && nnewy>=0 && vis[nnewx][nnewy]!=1)
{
pushdir[i][j][ii][jj][k]=1;
//up,down,left,right
}
}
}
}
}
}
lastans=inf;
memset(ansvis,0,sizeof(ansvis));
bfsans();
if(lastans==inf)cout<<"-1"<<endl;
else cout<<lastans<<endl;
}
return 0;
}