Pushing Boxes(推箱子)

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

原文地址:https://www.cnblogs.com/hpustudent/p/2185863.html