【BFS+DFS】hdu 1254 推箱子

来源:互联网 发布:网络兼职诈骗案开庭 编辑:程序博客网 时间:2024/06/06 01:26

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;}


原创粉丝点击