zoukankan      html  css  js  c++  java
  • 推箱子 BFS

    [编程题] 推箱子
    大家一定玩过“推箱子”这个经典的游戏。具体规则就是在一个N*M的地图上,有1个玩家、1个箱子、1个目的地以及若干障碍,其余是空地。玩家可以往上下左右4个方向移动,但是不能移动出地图或者移动到障碍里去。如果往这个方向移动推到了箱子,箱子也会按这个方向移动一格,当然,箱子也不能被推出地图或推到障碍里。当箱子被推到目的地以后,游戏目标达成。现在告诉你游戏开始是初始的地图布局,请你求出玩家最少需要移动多少步才能够将游戏目标达成。 
    输入描述:
    每个测试输入包含1个测试用例
    第一行输入两个数字N,M表示地图的大小。其中0<N,M<=8。
    接下来有N行,每行包含M个字符表示该行地图。其中 . 表示空地、X表示玩家、*表示箱子、#表示障碍、@表示目的地。
    每个地图必定包含1个玩家、1个箱子、1个目的地。


    输出描述:
    输出一个数字表示玩家最少需要移动多少步才能将游戏目标达成。当无论如何达成不了的时候,输出-1。

    输入例子:
    4 4
    ....
    ..*@
    ....
    .X..
    6 6
    ...#..
    ......
    #*##..
    ..##.#
    ..X...
    .@#...
    

    输出例子:
    3
    11
    题解:因为n,m较小,开四维数组搜下即可。
    #include <bits/stdc++.h>
    using namespace std;
    const int N=10;
    int dir[4][2]={{-1,0},{0,1},{0,-1},{1,0}};
    char c[N][N];
    int vis[N][N][N][N];
    int n,m,x,y,bx,by,ex,ey;
    bool check(int x,int y,int bx,int by)
    {
        if(x<0||x>=n||y<0||y>=m||c[x][y]=='#') return 1;
        if(bx<0||bx>=n||by<0||by>=m||c[bx][by]=='#') return 1;
        if(vis[x][y][bx][by]) return 1;
        return 0;
    }
    struct edge{
        int x,y,bx,by,step;
        edge(int x,int y,int bx,int by,int step)
        :x(x),y(y),bx(bx),by(by),step(step){}
        friend bool operator < (edge x,edge y)
        {
            return x.step>y.step;
        }
    };
    
    void bfs()
    {
        memset(vis,0,sizeof(vis));
        priority_queue<edge> q;
        edge c(x,y,bx,by,0);
        q.push(c);
        vis[x][y][bx][by]=1;
        while(!q.empty()){
            c=q.top();q.pop();
            if(c.bx==ex&&c.by==ey){
                printf("%d
    ",c.step);
                return ;
            }
            for(int i=0;i<4;i++)
            {
                int x=c.x+dir[i][0],y=c.y+dir[i][1];
                if(check(x,y,c.bx,c.by)) continue;
                ////这里不能先标记 因为推箱子可能从四个方向推过来的
                if(x==c.bx&&y==c.by){//碰到箱子
                    int tx=c.bx+dir[i][0];
                    int ty=c.by+dir[i][1];
                    if(check(x,y,tx,ty)) continue;
                    vis[x][y][tx][ty]=1;
                    edge ne(x,y,tx,ty,c.step+1);
                    q.push(ne);
                }
                else{//没碰到箱子
                    vis[x][y][c.bx][c.by]=1;
                    edge ne(x,y,c.bx,c.by,c.step+1);
                    q.push(ne);
                }
            }
        }
        puts("-1");
        return ;
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF){
            for(int i=0;i<n;i++) scanf("%s",c[i]);
            for(int i=0;i<n;i++)
                for(int j=0;j<m;j++)
                if(c[i][j]=='X') x=i,y=j;
                else if(c[i][j]=='*') bx=i,by=j;
                else if(c[i][j]=='@') ex=i,ey=j;
            bfs();
        }
        return 0;
    }
    
    
    
     
     
  • 相关阅读:
    hdu 1896 stones
    各种类型的取值范围
    RSS/PSS/VSZ
    kasan BUG log
    ARM机器码分析
    Linux进程状态
    谢宝友: 深入理解RCU之七:分级RCU实现
    rcu_preempt detected stalls on CPUs/tasks
    Linux 内核 hlist
    linux cmd
  • 原文地址:https://www.cnblogs.com/Ritchie/p/6612843.html
Copyright © 2011-2022 走看看