您的位置:首页 > 其它

hdu 1254 推箱子

2014-11-06 12:58 176 查看
/*

bfs+bfs,首先是上一步的人位置能否在某个方向推动箱子,然后就是箱子移动后的标记,开一个三维数组进行标记

前两维标记坐标,第三维标记箱子从什么方向推到该位置

*/

#include<stdio.h>

#include<queue>

#include<string.h>

using namespace std;

int Map[10][10][2],n,m,Map1[10][10][4],bu[4][2]={0,1,0,-1,1,0,-1,0},bu1[4][2]= {0,-1,0,1,-1,0,1,0},Map2[10][10];

struct node

{

int x1,y1,z;//点的横纵坐标和步数

int x2,y2;//人的推箱子后的坐标表

} S,D;

int bfs1(int a,int b,int c,int d)//是否能达到箱子的四周(a,b是人的位置,c,d是箱子四周的某一个位置)

{

int i;

queue<node> v;

while(!v.empty())

v.pop();

node l,r,t;

t.x1=a;

t.y1=b;

t.z=0;

memset(Map2,0,sizeof(Map2));

Map2[t.x1][t.y1]=1;

v.push(t);

while(!v.empty())

{

l=v.front();

v.pop();

if(l.x1==c&&l.y1==d)

return l.z;

for(i=0; i<4; i++)

{

int aa=l.x1+bu[i][0];

int bb=l.y1+bu[i][1];

if(aa>=0&&aa<n&&bb>=0&&bb<m&&Map[aa][bb][1]!=1&&Map2[aa][bb]==0)

{

Map2[aa][bb]=1;

r.x1=aa;

r.y1=bb;

r.z=l.z+1;

v.push(r);

if(r.x1==c&&r.y1==d)

return r.z;

}

}

}

return -1;

}

int bfs()

{

memset(Map1,0,sizeof(Map1));

queue<node> v;

int i;

node l,r;

while(!v.empty())

v.empty();

v.push(S);

while(!v.empty())

{

l=v.front();

v.pop();

if(l.x1==D.x1&&l.y1==D.y1)

return l.z;

for(i=0; i<4; i++)

{

int aa=bu[i][0]+l.x1;

int bb=bu[i][1]+l.y1;//箱子被推向的坐标(aa,bb)

if(aa>=0&&aa<n&&bb>=0&&bb<m&&Map1[aa][bb][i]==0&&Map[aa][bb][0]!=1)

{//当箱子被推的坐标满足在做表范围内,且不是同一方向被推向该点的时候,就能进入循环

int aa1=l.x1+bu1[i][0];

int bb1=l.y1+bu1[i][1];

if(Map[aa1][bb1][0]==1||aa1<0||aa1>=n||bb1<0||bb1>=m)

continue;//当箱子的四周为墙或者不在坐标范围内时,就不在向下判断

Map[l.x1][l.y1][1]=1;//先把地图中箱子的位置标记为墙进行广搜,然后再还原

int cc=bfs1(l.x2,l.y2,aa1,bb1);

Map[l.x1][l.y1][1]=0;//还原

if(cc==-1)//cc==-1说明没有搜到箱子的四周所以不用执行

continue;

r.x1=aa;//箱子被推向的位置的横坐标

r.y1=bb;//箱子被推向位置的纵坐标

r.z=l.z+1;//推箱子的步数+1

r.x2=l.x1;//箱子被推后人的位置就是箱子原来位置的横坐标

r.y2=l.y1;//箱子被推后人的位置就是箱子位置的纵坐标

Map1[aa][bb][i]=1;//标记箱子被推后的位置的已经被推过了,i表示从哪那个方向推到该位置的

v.push(r);

}

}

}

return -1;

}

int main()

{

int t,i,j;

//scanf("%d",&t);

while(scanf("%d%d",&n,&m)!=EOF)

{

for(i=0; i<n; i++)

for(j=0; j<m; j++)

{

scanf("%d",&Map[i][j][0]);

Map[i][j][1]=Map[i][j][0];//复制地图把除了1以外的都初始化为1

if(Map[i][j][0]==2)

{

S.x1=i;

S.y1=j;

S.z=0;

Map[i][j][1]=0;

}

if(Map[i][j][0]==4)

{

S.x2=i;

S.y2=j;

Map[i][j][1]=0;

}

if(Map[i][j][0]==3)

{

D.x1=i;

D.y1=j;

Map[i][j][1]=0;

}

}

int aa=bfs();

if(aa==0)

printf("-1\n");

else

printf("%d\n",aa);

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: