您的位置:首页 > 其它

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