POJ 3322 Bloxorz I(BFS)

题意:

要把x所在地方的盒子翻滚到O处,最少需要的滚动次数。

思路:

BFS 求最短路径,问题的关键是如何对盒子翻转时,移动状态的一个设计,开了一个三维数组。

#include <iostream>
#include <algorithm>
#include <deque>
using namespace std;

struct ST {
    int x, y;           // x, y 代表右下角的坐标位置
    int step, state;    // state = 0 竖立, state = 1 水平, state = 2 竖直
    ST() {}
    ST(int _x, int _y, int _step, int _state) 
        : x(_x), y(_y), step(_step), state(_state) {}
};

const int dir[3][4][3] = 
    {{{2,0,2},{-1,0,2},{0,-1,1},{0,2,1}},
    {{0,-2,0},{0,1,0},{-1,0,1},{1,0,1}}, 
    {{-2,0,0},{1,0,0},{0,1,2},{0,-1,2}}};

char grid[510][510];
bool vis[510][510][3];
int row, col;

bool judge(int x, int y, int state) {
    if (0 < x && x <= row && 0 < y && y <= col && grid[x][y] != '#') {
        if (state == 0 && grid[x][y] != 'E') {
            return true;
        }
        if (state == 1 && 1 < y && grid[x][y-1] != '#') {
            return true;
        }
        if (state == 2 && 1 < x && grid[x-1][y] != '#') {
            return true;
        }
    }
    return false;
}

int bfs(const ST& src, const ST& dst) {
    deque<ST> Q;
    Q.push_back(src);
    vis[src.x][src.y][src.state] = true;

    while (!Q.empty()) {
        ST u = Q.front();
        Q.pop_front();

        if (u.x == dst.x && u.y == dst.y && u.state == dst.state)
            return u.step;

        for (int i = 0; i < 4; i++) {
            int x = u.x + dir[u.state][i][0];
            int y = u.y + dir[u.state][i][1];
            int state = dir[u.state][i][2];
            if (!vis[x][y][state] && judge(x, y, state)) {
                vis[x][y][state] = true;
                Q.push_back(ST(x, y, u.step + 1, state));
            }
        }
    }
    return -1;
}

int main() {
    while (scanf("%d%d", &row, &col) && row && col) {
        ST src, dst;
        bool cflag = false;
        for (int i = 1; i <= row; i++) {
            scanf("%s", &grid[i][1]);
            for (int j = 1; j <= col; j++) {
                if (grid[i][j] == 'O') {
                    dst.x = i, dst.y = j, dst.state = 0;
                } else if (grid[i][j] == 'X') {
                    if (!cflag) {
                        cflag = true;
                        src.x = i, src.y = j, src.state = 0;
                    } else {
                        if (src.x == i) {
                            src.y = max(src.y, j);
                            src.state = 1;
                        } else if (src.y == j) {
                            src.x = max(src.x, i);
                            src.state = 2;
                        }
                    }
                }
                vis[i][j][0] = vis[i][j][1] = vis[i][j][2] = false;
            }
        }
        src.step = 0;
        int ans = bfs(src, dst);
        if (ans == -1) 
            printf("Impossible\n");
        else
            printf("%d\n", ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/kedebug/p/2981221.html