https://www.nowcoder.com/question/next?pid=4111169&qid=76262&tid=7218208
大家一定玩过“推箱子”这个经典的游戏。具体规则就是在一个N*M的地图上,有1个玩家、1个箱子、1个目的地以及若干障碍,其余是空地。玩家可以往上下左右4个方向移动,但是不能移动出地图或者移动到障碍里去。如果往这个方向移动推到了箱子,箱子也会按这个方向移动一格,当然,箱子也不能被推出地图或推到障碍里。当箱子被推到目的地以后,游戏目标达成。现在告诉你游戏开始是初始的地图布局,请你求出玩家最少需要移动多少步才能够将游戏目标达成。
输入描述:
每个测试输入包含1个测试用例 第一行输入两个数字N,M表示地图的大小。其中0<N,M<=8。 接下来有N行,每行包含M个字符表示该行地图。其中 . 表示空地、X表示玩家、*表示箱子、#表示障碍、@表示目的地。 每个地图必定包含1个玩家、1个箱子、1个目的地。
输出描述:
输出一个数字表示玩家最少需要移动多少步才能将游戏目标达成。当无论如何达成不了的时候,输出-1。
输入例子:
4 4 .... ..*@ .... .X.. 6 6 ...#.. ...... #*##.. ..##.# ..X... .@#...
输出例子:
3 11
一看就是一个bfs的题,按着模版慢慢写,然后发现不知道该怎么处理最后到不了的情况。
灵光一现,只要再设置一个数组,记录此时人的位置和箱子的位置,如果这个位置已经出现过了,则跳过~也就是我的f[10][10][10][10].
#include<bits/stdc++.h>
using namespace std;
int n,m;
char s[10][10];
int px,py;
struct node{
int x,y,cnt,sx,sy;
bool friend operator < (node a,node b)
{
return a.cnt>b.cnt;
}
};
int f[10][10][10][10];
node start;
int endx,endy;
int xx[4]={0,0,1,-1};
int yy[4]={1,-1,0,0};
void bfs()
{
priority_queue<node> q;
node c;
c.x=px;
c.y=py;
c.sx=start.x;
c.sy=start.y;
c.cnt=0;
q.push(c);
f[px][py][c.sx][c.sy]=1;
int flag=0;
while(!q.empty())
{
node d=q.top();
q.pop();
if(d.sx==endx&&d.sy==endy)
{
printf("%d\n",d.cnt);
return ;
}
for(int i=0;i<4;i++)
{
c.x=d.x+xx[i];
c.y=d.y+yy[i];
c.cnt=d.cnt+1;
if(s[c.x][c.y]=='#')
{
continue;
}
if(c.x==d.sx&&c.y==d.sy)
{
if(s[c.x+xx[i]][c.y+yy[i]]=='#')
{
continue;
}
if(c.x+xx[i]>=0&&c.x+xx[i]<n&&c.y+yy[i]>=0&&c.y+yy[i]<m)
{
c.sx=c.x+xx[i];
c.sy=c.y+yy[i];
if(f[c.x][c.y][c.sx][c.sy]==1)
{
continue;
}
f[c.x][c.y][c.sx][c.sy]=1;
q.push(c);
}
}
else
{
if(c.x>=0&&c.x<n&&c.y>=0&&c.y<m)
{
c.sx=d.sx;
c.sy=d.sy;
if(f[c.x][c.y][c.sx][c.sy]==1)
{
continue;
}
f[c.x][c.y][c.sx][c.sy]=1;
q.push(c);
}
}
}
}
printf("-1\n");
}
int main()
{
scanf("%d%d",&n,&m);
memset(f,0,sizeof(f));
for(int i=0;i<n;i++)
{
scanf("%s",s[i]);
for(int j=0;j<m;j++)
{
if(s[i][j]=='X')
{
px=i;
py=j;
}
if(s[i][j]=='*')
{
start.x=i;
start.y=j;
}
if(s[i][j]=='@')
{
endx=i;
endy=j;
}
}
}
bfs();
return 0;
}