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;

}

 

 

 

你可能感兴趣的:(push)