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;
}
浙公网安备 33010602011771号