poj 1475
题目大意:给出一个地形图,S表示人的起始位置,B表示箱子的位置,T表示要把箱子推倒的位置,刚开始的时候没看到要的是推箱子步数最少,其次是人的步子数最小。
解决:两个bfs,第一个bfs以箱子的位置为状态,箱子扩展到下一个状态扩展人的位置,最终的目的是箱子到达目标位置。
刚开始的时候是定义了一个vis[25][25][25][25] 的四维数组来标记状态是否已经存在,但是wa,后来仔细想了一下,这样会把正确的枝剪掉,四维数组在两个bfs中用不行,
若只有一个bfs还可以。
最终还是选择了两个标记数组,但是别忘了在每一个bfs之前要清除标记
#include <iostream> #include <queue> #include <string> using namespace std; int m,n; char map[25][25]; int sx,sy,bx,by,tx,ty; //bool vis[25][25][25][25]; bool visb[25][25]; bool vism[25][25]; int dx[]={1,-1,0,0}; int dy[]={0,0,1,-1}; char db[]="SNEW"; char dm[]="snew"; struct node { int x,y,bx,by; string p; node(int xx,int yy,int bbx,int bby,string pp):x(xx),y(yy),bx(bbx),by(bby),p(pp){} node(){} }; struct man { int x,y; string p; man(){} man(int xx,int yy,string pp):x(xx),y(yy),p(pp){} }; bool inmap(int x,int y) { return x>=0 && x<m && y>=0 && y<n; } bool bfsm(int sx,int sy,int tx,int ty,int bx,int by,string & path) { memset(vism,0,sizeof(vism)); queue<man> q; path=""; vism[sx][sy]=1; if(sx==tx && sy==ty){return 1;} q.push(man(sx,sy,path)); man now,next; while(!q.empty()) { now=q.front(); q.pop(); for(int i=0;i<4;i++) { next=man(now.x+dx[i],now.y+dy[i],now.p+dm[i]); if(inmap(next.x,next.y) && !vism[next.x][next.y] && map[next.x][next.y]!='#' ) if(!(next.x==bx && next.y==by)) { vism[next.x][next.y]=1; if(next.x==tx && next.y==ty){path=next.p;return 1;} q.push(next); } } } return 0; } bool bfs() { if(bx==tx && by==ty){cout<<endl;return 1;} memset(visb,0,sizeof(visb)); queue<node> q; q.push(node(sx,sy,bx,by,"")); visb[bx][by]=1; node now,next; int nx,ny; string p; while(!q.empty()) { now=q.front(); q.pop(); for(int i=0;i<4;i++) { next=node(now.x,now.y,now.bx+dx[i],now.by+dy[i],now.p); nx=now.bx-dx[i]; ny=now.by-dy[i]; if(inmap(next.bx,next.by) && map[next.bx][next.by]!='#' && !visb[next.bx][next.by]) { if( bfsm(now.x,now.y,nx,ny,now.bx,now.by,p) ) { visb[next.bx][next.by] = 1; next.p=now.p+p+db[i]; if(next.bx==tx && next.by==ty){cout<<next.p<<endl;return 1;} q.push(node(now.bx,now.by,next.bx,next.by,next.p)); } } } } return 0; } int main() { int T=1; while(cin>>m>>n && (m||n)) { for(int i=0;i<m;i++) { cin>>map[i]; for(int j=0;j<n;j++) { switch(map[i][j]) { case 'S':sx=i;sy=j;map[i][j]='.';break; case 'B':bx=i;by=j;map[i][j]='.';break; case 'T':tx=i;ty=j;map[i][j]='.';break; } } } cout<<"Maze #"<<T++<<endl; if(!bfs())puts("Impossible."); cout<<endl; } system("pause"); return 0; }