描述:
绝大多数人都玩过推箱子的游戏,控制一个人将箱子推动到目标位置即获得胜利。现请你编写一个程序,判断将箱子推到目标位置至少需要多少步。
输入:
推箱子的平面区域为固定大小(10*10),使用10行10列输入推箱子的初始局面。其中,0代表空格,1代表墙,2代表箱子,3代表目标位置,4代表人。
注:游戏中只有一个箱子,一个目标位置,一个人。
输出:
输出将箱子推到目标位置的最小步数;若箱子不可能被推到目标位置,输出-1。
输入样例:
0000000000 0000000300 0100000000 0100000000 0101111100 0000010000 0000010000 0020010040 0000010000 0000010000
输出样例:
34
#include<stdio.h>
#include<iostream>
#include<queue>
using namespace std;
#include<iostream>
#include<queue>
using namespace std;
//四位数组判重,状态为人的坐标和箱子的坐标。地图边框防止数组越界。
int ditu[12][12]={0},used[12][12][12][12]={0};
long long int di[12];
int rrow,rcol,mrow,mcol,zrow,zcol;
//四个方向在行,列的偏移量。
int dr[4]={0, 1, 0, -1};
int dc[4]={-1, 0, 1, 0};
int ditu[12][12]={0},used[12][12][12][12]={0};
long long int di[12];
int rrow,rcol,mrow,mcol,zrow,zcol;
//四个方向在行,列的偏移量。
int dr[4]={0, 1, 0, -1};
int dc[4]={-1, 0, 1, 0};
queue<int>q1;
queue<int>q2;
queue<int>q3;
queue<int>q4;
queue<int>q2;
queue<int>q3;
queue<int>q4;
void readdata();
void init();
int bfs();
int canmoveto(int n);
void init();
int bfs();
int canmoveto(int n);
int main()
{
int result;
readdata();
init();
result=bfs();
if(result==0)
{
cout<<"-1"<<endl;
return 0;
}
cout<<result<<endl;
return 0;
}
void readdata()
{
int i,j;
//读入数据。
for(i=1; i<11; i++)
{
cin>>di[i];
}
for(i=1; i<11; i++)
{
for(j=10; j>=0; j--)
{
ditu[i][j]=di[i]%10;
di[i]=di[i]/10;
if(ditu[i][j]==2)
{
mrow=i;
mcol=j;
}
if(ditu[i][j]==3)
{
zrow=i;
zcol=j;
}
if(ditu[i][j]==4)
{
rrow=i;
rcol=j;
ditu[i][j]=0;
}
}
}
}
void init()
{
int i=0, j=0;
//地图边框为1,表示不能走。
while(i<12)
{
ditu[i][0]=1;
ditu[i][11]=1;
i++;
}
while(j<12)
{
ditu[0][j]=1;
ditu[11][j]=1;
j++;
}
q1.push(rrow);
q2.push(rcol);
q3.push(mrow);
q4.push(mcol);
used[rrow][rcol][mrow][mcol]=1;
}
{
int i=0, j=0;
//地图边框为1,表示不能走。
while(i<12)
{
ditu[i][0]=1;
ditu[i][11]=1;
i++;
}
while(j<12)
{
ditu[0][j]=1;
ditu[11][j]=1;
j++;
}
q1.push(rrow);
q2.push(rcol);
q3.push(mrow);
q4.push(mcol);
used[rrow][rcol][mrow][mcol]=1;
}
int bfs()
{
int i,tmp;
int rrow1,rcol1,mrow1,mcol1;
while(!q1.empty())
{
rrow=q1.front();
q1.pop();
rcol=q2.front();
q2.pop();
mrow=q3.front();
q3.pop();
mcol=q4.front();
q4.pop();
//注意箱子的位置一定要在这说明,因为经过每一次队列变换都会变化。
ditu[mrow][mcol]=2;
for(i=0; i<4; i++)//人走的所有可能只有四个方向。
{
//判断这个方向能不能走,0表示不能走,1表示可走且前面不是箱子,2表示能走但前面是箱子
tmp=canmoveto(i);
if(tmp==1)
{
rrow1=rrow+dr[i];
rcol1=rcol+dc[i];
mrow1=mrow;
mcol1=mcol;
if(used[rrow1][rcol1][mrow1][mcol1]==0)
{
used[rrow1][rcol1][mrow1][mcol1]=used[rrow][rcol][mrow][mcol]+1;
q1.push(rrow1);
q2.push(rcol1);
q3.push(mrow1);
q4.push(mcol1);
}
}
if(tmp==2)
{
rrow1=rrow+dr[i];
rcol1=rcol+dc[i];
mrow1=mrow+dr[i];
mcol1=mcol+dc[i];
if(mrow1==zrow&&mcol1==zcol)
{
return used[rrow][rcol][mrow][mcol];
}
else if(used[rrow1][rcol1][mrow1][mcol1]==0)
{
used[rrow1][rcol1][mrow1][mcol1]=used[rrow][rcol][mrow][mcol]+1;
q1.push(rrow1);
q2.push(rcol1);
q3.push(mrow1);
q4.push(mcol1);
}
}
}
//把标记的箱子的位置去掉,让队列里下一个元素标记。
ditu[mrow][mcol]=0;
}
return 0;
}
{
int i,tmp;
int rrow1,rcol1,mrow1,mcol1;
while(!q1.empty())
{
rrow=q1.front();
q1.pop();
rcol=q2.front();
q2.pop();
mrow=q3.front();
q3.pop();
mcol=q4.front();
q4.pop();
//注意箱子的位置一定要在这说明,因为经过每一次队列变换都会变化。
ditu[mrow][mcol]=2;
for(i=0; i<4; i++)//人走的所有可能只有四个方向。
{
//判断这个方向能不能走,0表示不能走,1表示可走且前面不是箱子,2表示能走但前面是箱子
tmp=canmoveto(i);
if(tmp==1)
{
rrow1=rrow+dr[i];
rcol1=rcol+dc[i];
mrow1=mrow;
mcol1=mcol;
if(used[rrow1][rcol1][mrow1][mcol1]==0)
{
used[rrow1][rcol1][mrow1][mcol1]=used[rrow][rcol][mrow][mcol]+1;
q1.push(rrow1);
q2.push(rcol1);
q3.push(mrow1);
q4.push(mcol1);
}
}
if(tmp==2)
{
rrow1=rrow+dr[i];
rcol1=rcol+dc[i];
mrow1=mrow+dr[i];
mcol1=mcol+dc[i];
if(mrow1==zrow&&mcol1==zcol)
{
return used[rrow][rcol][mrow][mcol];
}
else if(used[rrow1][rcol1][mrow1][mcol1]==0)
{
used[rrow1][rcol1][mrow1][mcol1]=used[rrow][rcol][mrow][mcol]+1;
q1.push(rrow1);
q2.push(rcol1);
q3.push(mrow1);
q4.push(mcol1);
}
}
}
//把标记的箱子的位置去掉,让队列里下一个元素标记。
ditu[mrow][mcol]=0;
}
return 0;
}
int canmoveto(int n)
{
if(n==0)
{
if(ditu[rrow][rcol-1]==0)
{
return 1;
}
if(ditu[rrow][rcol-1]==2&&(ditu[rrow][rcol-2]==0||ditu[rrow][rcol-2]==3))
{
return 2;
}
return 0;
}
if(n==1)
{
if(ditu[rrow+1][rcol]==0)
{
return 1;
}
if(ditu[rrow+1][rcol]==2&&(ditu[rrow+2][rcol]==0||ditu[rrow+2][rcol]==3))
{
return 2;
}
return 0;
}
if(n==2)
{
if(ditu[rrow][rcol+1]==0)
{
return 1;
}
if(ditu[rrow][rcol+1]==2&&(ditu[rrow][rcol+2]==0||ditu[rrow][rcol+2]==3))
{
return 2;
}
return 0;
}
if(n==3)
{
if(ditu[rrow-1][rcol]==0)
{
return 1;
}
if(ditu[rrow-1][rcol]==2&&(ditu[rrow-2][rcol]==0||ditu[rrow-2][rcol]==3))
{
return 2;
}
return 0;
}
}
{
if(n==0)
{
if(ditu[rrow][rcol-1]==0)
{
return 1;
}
if(ditu[rrow][rcol-1]==2&&(ditu[rrow][rcol-2]==0||ditu[rrow][rcol-2]==3))
{
return 2;
}
return 0;
}
if(n==1)
{
if(ditu[rrow+1][rcol]==0)
{
return 1;
}
if(ditu[rrow+1][rcol]==2&&(ditu[rrow+2][rcol]==0||ditu[rrow+2][rcol]==3))
{
return 2;
}
return 0;
}
if(n==2)
{
if(ditu[rrow][rcol+1]==0)
{
return 1;
}
if(ditu[rrow][rcol+1]==2&&(ditu[rrow][rcol+2]==0||ditu[rrow][rcol+2]==3))
{
return 2;
}
return 0;
}
if(n==3)
{
if(ditu[rrow-1][rcol]==0)
{
return 1;
}
if(ditu[rrow-1][rcol]==2&&(ditu[rrow-2][rcol]==0||ditu[rrow-2][rcol]==3))
{
return 2;
}
return 0;
}
}