zoukankan      html  css  js  c++  java
  • 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;
    }
    

  • 相关阅读:
    【JS】js获得下拉列表选中项的值和id
    【Java】Java处理double相加的结果异常
    【JSP】弹出带输入框可 确认密码 对话框
    【MySQL】Java对SQL时间类型的操作(获得当前、昨天、前年。。时间)
    【MySQL】通过select语句把一列数据拼接成一条字符串
    【JSP】JSP向MySQL写入|读出中文数据——乱码问题
    【CSS】使用CSS改变超链接样式
    【JSP】三种弹出对话框的用法实例
    【JSP】<meta>标签用法
    【Mysql】安装 mysql-5.7.5 指南
  • 原文地址:https://www.cnblogs.com/hpustudent/p/2185863.html
Copyright © 2011-2022 走看看