【BFS+DFS】hdu 1254 推箱子
2013-08-11 16:00
489 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1254
分析:以箱子的路线为主,判断人是否能到达推箱子的地点,通过箱子只能走不同方向(vis[NM][NM][[4])一次标记
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int NM=10;
int a[4][2]={-1,0,1,0,0,1,0,-1};
int vis[NM][NM][4],vp[NM][NM];
int n,m,x1,x2,y1,y2,A1,B1,flag;
int str[NM][NM];
struct Box{
int bx,by,ans;
int px,py;
};
bool check(int x,int y)
{
if(x>=0&&x<n&&y>=0&&y<m&&str[x][y]!=1)
return 1;
else return 0;
}
void DFS1(int xx1,int yy1,int xx2,int yy2) //只是判断人能否到达,无论步数
{
if(xx1==xx2&&yy1==yy2)
{
flag=1;
return;
}
if(flag) return;
for(int i=0;i<4;i++)
{
int x=xx1+a[i][0];
int y=yy1+a[i][1];
if(check(x,y)&&!vp[x][y])
{
vp[x][y]=1;
DFS1(x,y,xx2,yy2);
}
}
}
void BFS()
{
queue<Box>q1;
Box t,p;
int i,xx1,xx2,yy1,yy2;
memset(vis,0,sizeof(vis));
t.bx=x1,t.by=y1;
t.px=A1,t.py=B1;
t.ans=0;
q1.push(t);
while(!q1.empty())
{
t=q1.front();q1.pop();
if(t.bx==x2&&t.by==y2)
{
printf("%d\n",t.ans);
return;
}
for(i=0;i<4;i++)
{
p.bx=t.bx+a[i][0],p.by=t.by+a[i][1];
xx1=t.px,yy1=t.py; //人起始位置
xx2=t.bx-a[i][0],yy2=t.by-a[i][1]; //人要到达位置
if(check(p.bx,p.by)&&check(xx2,yy2)&&!vis[t.bx][t.by][i])
{
memset(vp,0,sizeof(vp));
vp[t.bx][t.by]=1; //人不能穿过箱子
flag=0;
DFS1(xx1,yy1,xx2,yy2);
if(!flag) continue;
vis[t.bx][t.by][i]=1;
p.px=xx2,p.py=yy2;
p.ans=t.ans+1;
q1.push(p);
}
}
}
printf("-1\n");
}
int main()
{
int i,j,T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
scanf("%d",&str[i][j]);
if(str[i][j]==2)
x1=i,y1=j;
else if(str[i][j]==3)
x2=i,y2=j;
else if(str[i][j]==4) //人
A1=i,B1=j;
}
}
BFS();
}
return 0;
}
分析:以箱子的路线为主,判断人是否能到达推箱子的地点,通过箱子只能走不同方向(vis[NM][NM][[4])一次标记
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int NM=10;
int a[4][2]={-1,0,1,0,0,1,0,-1};
int vis[NM][NM][4],vp[NM][NM];
int n,m,x1,x2,y1,y2,A1,B1,flag;
int str[NM][NM];
struct Box{
int bx,by,ans;
int px,py;
};
bool check(int x,int y)
{
if(x>=0&&x<n&&y>=0&&y<m&&str[x][y]!=1)
return 1;
else return 0;
}
void DFS1(int xx1,int yy1,int xx2,int yy2) //只是判断人能否到达,无论步数
{
if(xx1==xx2&&yy1==yy2)
{
flag=1;
return;
}
if(flag) return;
for(int i=0;i<4;i++)
{
int x=xx1+a[i][0];
int y=yy1+a[i][1];
if(check(x,y)&&!vp[x][y])
{
vp[x][y]=1;
DFS1(x,y,xx2,yy2);
}
}
}
void BFS()
{
queue<Box>q1;
Box t,p;
int i,xx1,xx2,yy1,yy2;
memset(vis,0,sizeof(vis));
t.bx=x1,t.by=y1;
t.px=A1,t.py=B1;
t.ans=0;
q1.push(t);
while(!q1.empty())
{
t=q1.front();q1.pop();
if(t.bx==x2&&t.by==y2)
{
printf("%d\n",t.ans);
return;
}
for(i=0;i<4;i++)
{
p.bx=t.bx+a[i][0],p.by=t.by+a[i][1];
xx1=t.px,yy1=t.py; //人起始位置
xx2=t.bx-a[i][0],yy2=t.by-a[i][1]; //人要到达位置
if(check(p.bx,p.by)&&check(xx2,yy2)&&!vis[t.bx][t.by][i])
{
memset(vp,0,sizeof(vp));
vp[t.bx][t.by]=1; //人不能穿过箱子
flag=0;
DFS1(xx1,yy1,xx2,yy2);
if(!flag) continue;
vis[t.bx][t.by][i]=1;
p.px=xx2,p.py=yy2;
p.ans=t.ans+1;
q1.push(p);
}
}
}
printf("-1\n");
}
int main()
{
int i,j,T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
scanf("%d",&str[i][j]);
if(str[i][j]==2)
x1=i,y1=j;
else if(str[i][j]==3)
x2=i,y2=j;
else if(str[i][j]==4) //人
A1=i,B1=j;
}
}
BFS();
}
return 0;
}
相关文章推荐
- hdu 1254 推箱子(嵌套搜索,bfs中有dfs)
- bfs+bfs/dfs hdu 1254 推箱子1
- 【HDU】1254 推箱子(BFS DFS HASH记录走过的状态)
- hdu 1254 推箱子(BFS+BFS或BFS+DFS)
- hdu 1254 推箱子 (bfs+dfs+预处理)
- HDU 1254 推箱子 (BFS + DFS)
- HDU 1254:推箱子【DFS && BFS】
- HDU 1254 推箱子 (搜索中套搜索,BFS + DFS 这感觉,酸爽!)
- HDU 1254推箱子(bfs+dfs)
- HDU1254--推箱子(BFS+DFS)
- HDU 1254 - 推箱子(BFS + DFS)
- HDU 1254 推箱子(BFS + DFS)
- HDOJ 1254 推箱子【bfs && dfs】
- HDU1254 推箱子 双BFS
- HDU 1254 推箱子(双重bfs)
- HDOJ 1254 推箱子(bfs+dfs)
- HDU 1254 推箱子(BFS)
- hdu 1254 推箱子 很好的嵌套搜索 双层BFS
- HDU 1254 推箱子 (BFS套BFS)
- hdu 1254 推箱子(bfs + bfs)