题目

题目描述:
Nancy喜欢吃果冻!
Nancy钻进了一个n×n×n的果冻里,她想从(1,1,1)一路上、下、左、右、前、后六个方向吃到(n,n,n)。
但果冻毕竟是有许多口味的,标记为*的口味是Nancy不愿意吃的,其余的果冻均标记为.。
Nancy不想吃坏肚子,于是她想尽可能少的吃果冻。
下面给出果冻的情况,请你帮忙计算一下她能吃多少块果冻叭!

输入描述:
第一行:一个整数n。
接下来n层,每组n行,每行n列,表示果冻(i,j,k)的情况(如题目描述所述)。
数据满足:1≤n≤100,保证果冻(1,1,1)不是Nancy不愿意吃的。

输出描述:
如果可以到达(n,n,n),请输出路上吃的果冻数量,否则请输出-1。


解析

题就是简单的bfs
操作操作:
  1. 三维数组作为地图(mp数组)保存题目信息,建立一个已访问数组(visited数组)保存节点的访问信息,保证每个节点不被重复访问。
  2. 队列对地图进行遍历。先将起点进队,然后访问起点可以到达的所有节点(地图外和禁止区域当然就不让访问了)
  3. 然后依次类推,每次将队首节点拿出来访问,直到访问到终点。
  4. 因为我们队列保存的是结构体,每个节点自带步数。(步数自然等于访问他的节点+1)所以输出该节点的步数就好了。


代码

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
#define js ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
const int MAX = 1e2 + 7;
//代码预处理
int walk[6][3] = { {1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1} };//三轴移动
int visited[MAX][MAX][MAX], mp[MAX][MAX][MAX], n;//已访问数组,地图,大小
typedef struct {
    int x, y, z, eat;//坐标与吃的数量
} Node;

int judge(Node next);//判断接下来访问的节点是否是合法位置(墙或者不能走的格子)
int dfs();//广度优先遍历

int main() {
    js;
    cin >> n;
    memset(mp, -1, sizeof(mp));
    for (int k = 1; k <= n; k++)
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++) {
                char ch; cin >> ch;
                if (ch == '.') mp[i][j][k] = 0;
            }
        //初始化地图数组
    cout << dfs() << endl;
    return 0;
}

int judge(Node next) {
    if (mp[next.x][next.y][next.z]) return 0;//判墙或者不能走的节点
    if (visited[next.x][next.y][next.z]) return 0;//判是否走过
    return 1;
}
int dfs() {
    memset(visited, 0, sizeof(visited));
    visited[1][1][1] = 1;
    Node top; top.x = 1; top.y = 1; top.z = 1; top.eat = 1;
    queue<Node> que; que.push(top);
        //队列与访问数组初始化
    while (!que.empty()) {
        top = que.front(); que.pop();
        if (top.x == n && top.y == n && top.z == n) return top.eat;
                //抵达终点则有数量返回,否则最后会全部出队返回-1
        for (int i = 0; i < 6; i++) {
            Node next;
            next.x = top.x + walk[i][0];
            next.y = top.y + walk[i][1];
            next.z = top.z + walk[i][2];
            next.eat = top.eat + 1;
                        //得到下一个节点
            if (judge(next)) {
                que.push(next);
                visited[next.x][next.y][next.z] = 1;
            }
                        //可走则进队
        }
    }
    return -1;
}