POJ 1475 Pushing Boxes (BFS+BFS)
题意:模拟推箱子游戏给出一个二维图,S表示人的位置,B表示箱子位置,T表示目标位置。要求最短输出路径大写字母代表推,小写字母代表走。
思路:BFS+BFS,首先对箱子进行BFS,每一次在加入新的节点时对人再进行一次BFS,找到他走到需要推箱子的地方的最小路径。(最开始不知道怎么记录路径,之前也几乎不用String,结果如此好用,还可以直接加。。。)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<queue> #include<iostream> #include<vector> using namespace std; char s[30][30],n,m; int bx,by,sx,sy,tx,ty; int fx[]={-1,1,0,0}; int fy[]={0,0,-1,1}; int vis[30][30][4],vis2[30][30]; char ch[]={'N','S','W','E'}; char ch2[]={'n','s','w','e'}; struct node{ int x,y;//箱子位置 int sx,sy;//人的位置 string path;//路径 }; bool in(int x,int y) { return x>=0&&y>=0&&x<n&&y<m; } bool bfs2(int ex,int ey,int bbx,int bby,int ssx,int ssy,string &str){ //分别代表这次人移动目标位置,箱子在哪里(不能走),人在哪里和路径。 memset(vis2,0,sizeof(vis2)); queue<node> qs; node no; no.x=ssx; no.y=ssy; no.path=str; qs.push(no); while(!qs.empty()){ node us=qs.front(); qs.pop(); if(us.x==ex&&us.y==ey){ str=us.path; return true; } for(int i=0;i<4;i++){ int xx=fx[i]+us.x; int yy=fy[i]+us.y; if(xx==bbx&&yy==bby) continue; if(!vis2[xx][yy]&&in(xx,yy)&&s[xx][yy]!='#'){ vis2[xx][yy]=1; node no1; no1.x=xx; no1.y=yy; no1.path=us.path+ch2[i]; qs.push(no1); } } } return false; } bool bfs(){ memset(vis,0,sizeof(vis)); queue<node> qb; node no; no.x=bx; no.y=by; no.sx=sx; no.sy=sy; no.path=""; qb.push(no); while(!qb.empty()){ node ub=qb.front(); qb.pop(); if(ub.x==tx&&ub.y==ty){ cout<<ub.path<<endl; return true; } for(int i=0;i<4;i++){ int xx=fx[i]+ub.x; int yy=fy[i]+ub.y; if(in(xx,yy)&&(!vis[xx][yy][i])&&(s[xx][yy]!='#')){ vis[xx][yy][i]=1; string temp=ub.path; if(bfs2(ub.x-fx[i],ub.y-fy[i],ub.x,ub.y,ub.sx,ub.sy,temp)){ node no1; no1.x=xx; no1.y=yy; no1.sx=ub.x; no1.sy=ub.y; no1.path=temp+ch[i]; qb.push(no1); } } } } return false; } int main(){ int t=0; while(~scanf("%d%d",&n,&m)){ if(n==0&&m==0) break; for(int i=0;i<n;i++) scanf("%s",s[i]); for(int i=0;i<n;i++) for(int j=0;j<m;j++){ if(s[i][j]=='S'){ sx=i; sy=j; } else if(s[i][j]=='B'){ bx=i; by=j; } else if(s[i][j]=='T'){ tx=i; ty=j; } } t++; printf("Maze #%d\n",t); if(!bfs()) printf("Impossible.\n"); cout<<endl; } return 0; }