1326.推箱子
时限:1000ms 内存限制:10000K 总时限:3000ms
- 描述
绝大多数人都玩过推箱子的游戏,控制一个人将箱子推动到目标位置即获得胜利。现请你编写一个程序,判断将箱子推到目标位置至少需要多少步。
- 输入
推箱子的平面区域为固定大小(10*10),使用10行10列输入推箱子的初始局面。其中,0代表空格,1代表墙,2代表箱子,3代表目标位置,4代表人。
注:游戏中只有一个箱子,一个目标位置,一个人。
- 输出
输出将箱子推到目标位置的最小步数;若箱子不可能被推到目标位置,输出-1。
- 样例
输入样例
0000000000
0000000300
0100000000
0100000000
0101111100
0000010000
0000010000
0020010040
0000010000
0000010000
输出样例
34
-
思路
bfs,每个状态是一个五元组,箱子的横纵坐标+人的横纵坐标+走到当前的最小步数。每个状态由人的位置向上下左右四个方向拓展状态,判断下一步是否合法,是否是箱子的位置,若是箱子的位置,则判断箱子朝当前方向的下一步是否合法,以此进行状态拓展,达到目标状态则返回,遇到重复状态则跳过,直到队列为空 -
问题
一开始写的时候忘记判断若箱子跟着人一同前进的情况下,箱子的位置是否合法了
- 附上代码
#include<iostream>
#include<queue>
using namespace std;
int tx,ty;
bool area[10][10];
struct node
{
int bx, by, rx, ry,step;
node(int _bx,int _by,int _rx,int _ry,int _step){step=_step,bx=_bx,by=_by,rx=_rx,ry=_ry;}
};
queue<node> q;
bool fg[10][10][10][10];
int dirx[4]={0,0,-1,1};
int diry[4]={1,-1,0,0};
int bfs(int bx, int by, int rx, int ry) ;
int main()
{
char c;
int bx, by, rx, ry;
for (int i = 0; i < 10; ++i)
{
for(int j=0;j<10;++j)
{
cin>>c;
switch(c)
{
case '1':area[i][j]=1;break;
case '2':bx=i,by=j;break;
case '3':tx=i,ty=j;break;
case '4':rx=i,ry=j;break;
}
}
}
cout<<bfs(bx,by,rx,ry)<<endl;
return 0;
}
int bfs(int bx,int by,int rx,int ry)
{
q.push(node(bx,by,rx,ry,0));
while(!q.empty())
{
node nd=q.front();
q.pop();
int bxx=nd.bx,byy=nd.by;
if(bxx==tx&&byy==ty)return nd.step;
int rxx=nd.rx,ryy=nd.ry;
//cout<<bxx<<' '<<byy<<' '<<rxx<<' '<<ryy<<endl;
if(fg[bxx][byy][rxx][ryy])continue;
fg[bxx][byy][rxx][ryy]=1;
for(int i=0;i<4;++i)
{
int x=rxx+dirx[i],y=ryy+diry[i];
if(x>=0&&x<10&&y>=0&&y<10&&!area[x][y])
{
if(x==bxx&&y==byy)
{
int xx=x+dirx[i],yy=y+diry[i];
if(xx>=0&&xx<10&&yy>=0&&yy<10&&!area[xx][yy])
q.push(node(xx,yy,x,y,nd.step+1));
}
else
{
q.push(node(bxx,byy,x,y,nd.step+1));
}
}
}
}
return -1;
}