【练习】Jelly

Jelly

https://ac.nowcoder.com/acm/problem/201613


题目

题目描述:
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;
}
牛客算法竞赛入门课题解 文章被收录于专栏

憨憨的专栏

全部评论

相关推荐

“无名小卒,还是名扬天下?”我知道很多人都不觉得我能走到今天这一步,当然,也包括我自己。在我的人生里,有两部作品刻下了最深的烙印:《斗破苍穹》与《龙族》。它们总被人拿来对照:一边是萧炎的桀骜轻狂,一边是路明非的怯懦衰颓。有人说,天蚕土豆没见过魂天帝,但江南见过真凯撒。我时常觉得,自己就是那个衰小孩路明非。可路明非可以开挂,我不可以;我也无数次幻想过,能拥有萧炎那般年少轻狂的人生,可我没有他与生俱来的逆天天赋。我只是个平庸的普通人,一个看过《斗破苍穹》却开不了挂的路明非,只能一步一步往上爬。从我下定决心找实习的那一刻起,我就给自己定下了目标:“我一定要为字节跳动卖命.jpg”。萧炎有他的三年之约,我有我的两年半之约(其实是一年半)。2024.11.20,科大讯飞的第一封实习offer落进邮箱,我迈出了这场奔赴的第一步。2025.8.18,放弃百度转正的安稳机会,转身走进前路未卜的不确定里。我很感谢我在百度的mentor,是她从茫茫人海选中了我,给了我大厂实习的机会。即便有段时间我状态差、产出不理想,她依旧愿意认可我、希望我留下转正。2025.11.14,我选择走进字节跳动,以实习生的身份重新出发。2026.3.25&nbsp;-&nbsp;3.31,一周速通上海飞书,幸遇赏识我的伯乐,斩获Special&nbsp;Offer。被告知面试通过的那一刻,我的内心无比平静,就像这个offer本就该属于我。不是侥幸,是应得的。这一路,有人看轻过我的出身,不相信我能走到这里;也有人在我看不见前路的时候,替我举过灯。没有他们的鼓励与支撑,就没有今天站在这里的我。我看到了自强不息的激荡,那是一个双非的伟大乐章!我是雨夜迈巴赫,我要开启属于我的新篇章了。
在看牛客的本杰明很勇...:真心祝贺l总 我永远的偶像 我滴神
春招至今,你收到几个面试...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务