2018秋招 今日头条1017 推箱子

题目描述

给定一个矩阵,“#”表示障碍,“.”表示空地,“S”表示人开始的位置,“E”表示箱子的结束位置,“0”表示箱子的初始位置。现要将箱子从“0”位置推到“E”位置。
要求:不能将箱子推到“#”上,也不能将箱子推出边界。
请计算出最少几步能完成游戏,如果不能完成,则输出-1。

输入描述

第一行为2个数字:n, m,表示游戏盘面大小有n行m列(5 < n,m < 50), 后面为n行字符串,每行字符串有m字符,表示游戏盘面。

输出描述

一个数字,表示最少几步能完成游戏,如果不能,输出-1。

样例输入

3 6
.S#..E
.#.0..
……

样例输出

11

题目分析

典型的迷宫搜索问题,求最短时间,我们首先想到BFS。
和典型的迷宫搜索问题不同的是,本题中的搜索可以分为两个阶段。
第一阶段:游戏玩家从起始位置“S”走到箱子的位置(箱子的上、下、左、右)。
第二阶段:游戏玩家把箱子从“0”位置推到“E”位置。
在第一阶段中,和普通的BFS一样。在第二阶段中,玩家要和箱子一起移动。举个栗子,

..RX. ⇒ …RX

如上图所示,玩家R将箱子向右移动一个格子。我们可以看到,玩家和箱子两个方格构成了一个整体,玩家和箱子一起移动。
所以,在第二阶段的移动中,每一次要移动两个方格。

AC代码

#include 
#include 
#include 

using std::vector;
using std::queue;
using std::cin;
using std::cout;

int st[100][100][100][100];
int x, y, bx, by, tx, ty;
int m, n;
vector<vector<char>> mm;

bool valid(int x, int y) {
    if (x >= 0 && x < m && y >= 0 && y < n && mm[x][y] != '#')return true;
    return false;
}

int main() {

    cin >> m >> n;
    mm = std::vector<std::vector<char>>(m, vector<char>(n));

    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++) {
            char t;
            cin >> t;
            if (t == 'S') {
                x = i;
                y = j;
                // cout <
            }
            if (t == '0') {
                bx = i;
                by = j;
            }
            if (t == 'E') {
                tx = i;
                ty = j;
            }
            mm[i][j] = t;
        }

    vector<vector<int>> next = {{-1, 0},{1,  0},{0,  1},{0,  -1}};
    queue<vector<int>> que;
    que.push({x, y, bx, by});

    st[x][y][bx][by] = 1;
    while (!que.empty()) {
        vector<int> t = (vector<int> &&) que.front();
        que.pop();
        x = t[0];
        y = t[1];
        bx = t[2];
        by = t[3];
        for (int i = 0; i < next.size(); i++) {
            int nx = x + next[i][0], ny = y + next[i][1];
            int nnx = nx + next[i][0], nny = ny + next[i][1];
            // 玩家从开始位置走到箱子的位置
            if (valid(nx, ny) && (nx != bx || ny != by) && st[nx][ny][bx][by] == 0) {
                st[nx][ny][bx][by] = st[x][y][bx][by] + 1;
                que.push({nx, ny, bx, by});
                continue;
            } 
            // 玩家把箱子推到指定位置
            else if (nx == bx && ny == by && valid(nnx, nny) && st[nx][ny][nnx][nny] == 0) {
                st[nx][ny][nnx][nny] = st[x][y][bx][by] + 1;
                if (mm[nnx][nny] == 'E') {
                    cout << st[nx][ny][nnx][nny] - 1;
                    return 0;
                }
                que.push({nx, ny, nnx, nny});
            }
        }
    }

    cout << -1;
    return 0;
}

你可能感兴趣的:(搜索,--,BFS/DFS)