poj-2251

31 篇文章 0 订阅
//788K  0MS G++
#include <cstdio>
#include <queue>
#include <cstring>

#define MAX 50
using namespace std;

char maze[MAX][MAX][MAX]; // z , y, x

struct Pos {
    int x;
    int y;
    int z;
    int time;
};

typedef struct Pos Pos;

queue<Pos> BFSQueue;
char BFSFlag[MAX][MAX][MAX];

using namespace std;

int W;
int H;
int C; // the level num of maze

int Sx;
int Sy;
int Sz;

int Ex;
int Ey;
int Ez;

char checkNode(int curX, int curY, int curZ, int curTime) {
    BFSFlag[curX][curY][curZ] = 1;
    Pos newPos;
    if (curX == Ex && curY == Ey && curZ == Ez) {
        return curTime + 1;
    }
    newPos.x = curX;
    newPos.y = curY;
    newPos.z = curZ;
    newPos.time = curTime + 1;
    BFSQueue.push(newPos);
    return 0;
}

int BFS() {
    while(BFSQueue.size()) {
        BFSQueue.pop();
    }
    memset(BFSFlag, 0, sizeof(BFSFlag));

    Pos beginPos;
    beginPos.x = Sx;
    beginPos.y = Sy;
    beginPos.z = Sz;
    beginPos.time = 0;
    BFSFlag[Sx][Sy][Sz] = 1;
    BFSQueue.push(beginPos);

    while(BFSQueue.size()) {
        Pos curPos = BFSQueue.front();
        BFSQueue.pop();
        int curX = curPos.x;
        int curY = curPos.y;
        int curZ = curPos.z;
        int curTime = curPos.time;

        //head top
        if (curZ + 1 <= C-1 &&
            maze[curZ+1][curY][curX] != '#' &&
            !BFSFlag[curX][curY][curZ+1]) {
            if (checkNode(curX, curY, curZ+1, curTime)) {
                return curTime + 1;
            }
        }

        //under foot
        if (curZ > 0 &&
            maze[curZ-1][curY][curX] != '#' &&
            !BFSFlag[curX][curY][curZ-1]) {
            if (checkNode(curX, curY, curZ-1, curTime)) {
                return curTime + 1;
            }
        }

        // front
        if (curY +1 <= H-1 &&
            maze[curZ][curY+1][curX] != '#' &&
            !BFSFlag[curX][curY+1][curZ]) {
            if (checkNode(curX, curY+1, curZ, curTime)) {
                return curTime + 1;
            }
        }

        // back
        if (curY > 0 &&
            maze[curZ][curY-1][curX] != '#' &&
            !BFSFlag[curX][curY-1][curZ]) {
            if (checkNode(curX, curY-1, curZ, curTime)) {
                return curTime + 1;
            }
        }

        // left
        if (curX > 0 &&
            maze[curZ][curY][curX-1] != '#' &&
            !BFSFlag[curX-1][curY][curZ]) {
            if (checkNode(curX-1, curY, curZ, curTime)) {
                return curTime + 1;
            }
        }

        //right
        if (curX + 1 <= W-1 &&
            maze[curZ][curY][curX+1] != '#' &&
            !BFSFlag[curX+1][curY][curZ]) {
            if (checkNode(curX+1, curY, curZ, curTime)) {
                return curTime + 1;
            }
        }
    }

    return -1; // trapped!
}

void solve() {
    int res = BFS();
    if (res == -1) {
        printf("Trapped!\n");
    } else {
        printf("Escaped in %d minute", res);
        if (res > 1) {
            printf("(s).\n");
        } else {
            printf(".\n");
        }
    }
}

int main () {
    while(1) {
        scanf("%d %d %d", &C, &H, &W);
        if (C == 0 && H ==0 && W ==0) {
            return 0;
        }
        for (int i = 0; i < C; i++) {
            for (int j = 0; j < H; j++) {
                scanf("%s", maze[i][j]);
                for (int k = 0; k < W; k++) {
                    if (maze[i][j][k] == 'S') {
                        Sz = i;
                        Sy = j;
                        Sx = k;
                    } else if (maze[i][j][k] == 'E') {
                        Ez = i;
                        Ey = j;
                        Ex = k;
                    }
                }
            }
        }
        solve();
    }
}

一道变种迷宫最短路径题,不同的是,从2D迷宫变成了3D迷宫,除了二维的四个方向以外,又增加了头顶和脚下两个方向,其他的都没啥变化,

还是直接BFS求(不过分类这道题在DFS, DFS可以解出来,不过效率显然不高,并且本题的状态保存也只是三个坐标,不存在状态不好保存的问题)

描述迷宫的数组也相应的从二维数组变成了三维,直接用三维字符数组maze保存了,只不过坐标对应是 maze[z][y][x], 其他都一样。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值