【笔试】推箱子

题目

大家一定玩过“推箱子”这个经典的游戏。具体规则就是在一个N*M的地图上,有1个玩家、1个箱子、1个目的地以及若干障碍,其余是空地。玩家可以往上下左右4个方向移动,但是不能移动出地图或者移动到障碍里去。如果往这个方向移动推到了箱子,箱子也会按这个方向移动一格,当然,箱子也不能被推出地图或推到障碍里。当箱子被推到目的地以后,游戏目标达成。现在告诉你游戏开始是初始的地图布局,请你求出玩家最少需要移动多少步才能够将游戏目标达成

输入

每个测试输入包含1个测试用例
第一行输入两个数字N,M表示地图的大小。其中0<N,M<=8。
接下来有N行,每行包含M个字符表示该行地图。其中 . 表示空地、X表示玩家、*表示箱子、#表示障碍、@表示目的地。
每个地图必定包含1个玩家、1个箱子、1个目的地。

输出

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

Sample 

5 7
****E**
*###0#*
*****#*
*****#S
******#

3 11
***********
****0**E**S
***********

14

12

代码

#include<iostream>
#include<stdio.h>
#include<queue>
#include<vector>
using namespace std;

int st[50][50][50][50];
    int n, m;
    vector<string> ns;
struct Pos {
    int px, py, bx, by;
    Pos(int a, int b, int c, int d) {
        px = a,
        py = b, 
        bx = c,
        by = d;
    }
};
bool valid(int x, int y) {
    if (x >= n || x < 0 || y >= m || y < 0 || ns[x][y] == '#') {
        return false;
    }
    return true;
}
#include<string.h>
int main() {
    int N;
    string s;
    while (cin >> n >> m) {
        ns.clear();
        for (int i = 0; i < n; i++) {
            cin >> s;
            ns.push_back(s);
        }
        int sx, sy, ex, ey, bx, by;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (ns[i][j] == 'S') {
                    sx = i, sy = j;
                }
                if (ns[i][j] == '0') {
                    bx = i, by = j;
                }
                if (ns[i][j] == 'E') {
                    ex = i, ey = j;
                }
            }
        }
        Pos start = Pos(sx, sy, bx, by);
        queue<Pos> que;
        que.push(start);
        int dx[] = {1, -1, 0, 0};
        int dy[] = {0, 0, -1, 1};
        int k = 0;
        memset(st, 0, sizeof(st));
        // remember to set the origin to 1 or it will be visited
        st[sx][sy][bx][by] = 1;
        bool suc = false;
        while (!que.empty()) {
            Pos f = que.front();
            que.pop();
            for (int i = 0; i < 4; i++) {
                // the next position of worker
                int nx = f.px + dx[i], ny = f.py + dy[i];
                if (!valid(nx, ny)) {
                    continue;
                }
                int nbx = 0, nby = 0;
                // if the box is met, move it by the direction
                if (nx == f.bx && ny == f.by) {
                    nbx = nx + dx[i], nby = ny + dy[i];
                    if (!valid(nbx, nby) || st[nx][ny][nbx][nby] != 0) {
                        continue;
                    }
                    st[nx][ny][nbx][nby] = st[f.px][f.py][f.bx][f.by] + 1;
                    Pos e = Pos(nx, ny, nbx, nby);
                    que.push(e);
                    if (ns[nbx][nby] == 'E') {
                        cout << st[nx][ny][nbx][nby] - 1 << endl;
                        suc = true;
                        break;
                    }
                }
                else {
                    if (st[nx][ny][f.bx][f.by] != 0) {
                        continue;
                    }
                    Pos e = Pos(nx, ny, f.bx, f.by);
                    st[nx][ny][f.bx][f.by] = st[f.px][f.py][f.bx][f.by] + 1;
                    que.push(e);
                }
            }
            if (suc) {break;}
        }
        if (!suc) cout << -1 << endl;
    }
    return 0;
}

 

posted @ 2017-10-25 00:44  stackupdown  阅读(261)  评论(0编辑  收藏  举报