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;
}
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;
}
相关文章推荐
- HDU 1254 推箱子 解题报告
- HDU 1254 推箱子(BFS + DFS)
- hdu_1254_推箱子(双BFS)
- HDU 1254—— 推箱子
- HDU ACM 1254 推箱子 (两层广搜 + 位运算标记)
- HDU1254--推箱子(BFS+DFS)
- HDU - 1254 推箱子【bfs+bfs】
- HDU1254推箱子(AC)
- hdu 1254 推箱子(搜索)
- 题解: HDU 1254 :推箱子 (BFS)
- HDU 1254 推箱子(搜索)
- hdu 1254 推箱子
- Hdu 1254 推箱子
- HDU - 1254 推箱子(BFS+优先队列)
- ACM 搜索 HDU 1254 推箱子
- hdu 1254 推箱子(BFS)
- HDU1254 推箱子 双BFS
- hdu 1254 推箱子
- HDU - 1254 推箱子
- hdu(1254)推箱子