华为OD机试 - 周末爬山 - 广度优先搜索BFS(Python/JS/C/C++ 2024 E卷 200分)

news2024/11/24 15:25:56

在这里插入图片描述

华为OD机试 2024E卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

周末小明准备去爬山锻炼,0代表平地,山的高度使用1到9来表示,小明每次爬山或下山高度只能相差k及k以内,每次只能上下左右一个方向上移动一格,小明从左上角(0,0)位置出发

二、输入描述

第一行输入n m k(空格分隔)

代表n*m的二维山地图,k为小明每次爬山或下山高度差的最大值,然后接下来输入山地图,一共m行n列,均以空格分隔。取值范围:

0 < m <= 500
0 < n <= 500
0 < k <= 5

备注

所有用例输入均为正确格式,且在取值范围内,考生不需要考虑输入格式非法的情况。

三、输出描述

请问小明能爬到的最高峰是多少, 到该最高峰的最短步数,输出以空格分隔。

同高度的山峰输出较小步数。

如果没有可以爬的山峰,则高度和步数均返回0

四、测试用例

测试用例1:

1、输入

5 4 1
0 1 2 0
1 0 0 0
1 0 1 2
1 3 1 0
0 0 0 9

2、输出

2 2

3、说明

根据山地图可知,能爬到的最高峰在(0,2)位置,高度为2,最短路径为(0,0)-(0,1)-(0,2),最短步数为2。

测试用例2:

1、输入

5 4 3
0 0 0 0
0 0 0 0
0 9 0 0
0 0 0 0
0 0 0 9

2、输出

0 0

3、说明

根据山地图可知,每次爬山距离3,无法爬到山峰上,步数为0。

五、解题思路

本题是一个典型的二维网格搜索问题。小明从地图的左上角(0, 0)出发,每次只能上下左右移动一格,爬山或下山的高度差不能超过k。那么这就是一个 广度优先搜索(BFS) 问题,我们可以使用BFS遍历整个地图,记录每个位置的最短步数和能达到的最高峰值。

具体步骤如下:

  1. 初始化:从起点(0, 0)开始,将其加入队列,同时记录步数。
  2. BFS搜索:利用队列每次取出当前位置,尝试向上下左右四个方向移动,判断是否可以移动。如果可以移动,则记录该位置的步数并加入队列。
  3. 高度条件判断:每次移动时需要判断目标位置的高度与当前高度差是否在k的范围内。
  4. 结果记录:在遍历过程中记录最高峰及其最短步数,最终输出结果。如果没有可爬的山峰,则输出高度和步数均为0。

六、Python算法源码

from collections import deque

# 定义四个方向:上、下、左、右
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]

def bfs(map, m, n, k):
    # 队列用于BFS存储 [x坐标, y坐标, 当前步数]
    queue = deque()
    visited = [[False] * n for _ in range(m)]  # 记录访问过的位置
    queue.append((0, 0, 0))  # 从左上角(0, 0)出发,步数为0
    visited[0][0] = True

    max_height = map[0][0]  # 最高峰高度
    min_steps = 0  # 最短步数

    while queue:
        x, y, steps = queue.popleft()

        # 尝试四个方向移动
        for i in range(4):
            new_x = x + dx[i]
            new_y = y + dy[i]

            # 判断新位置是否在地图范围内
            if 0 <= new_x < m and 0 <= new_y < n and not visited[new_x][new_y]:
                # 判断高度差是否符合条件
                if abs(map[new_x][new_y] - map[x][y]) <= k:
                    visited[new_x][new_y] = True
                    queue.append((new_x, new_y, steps + 1))

                    # 更新最高峰和最短步数
                    if map[new_x][new_y] > max_height:
                        max_height = map[new_x][new_y]
                        min_steps = steps + 1
                    elif map[new_x][new_y] == max_height and (steps + 1) < min_steps:
                        min_steps = steps + 1

    # 如果最高峰和起点相同(即无法爬山),返回高度和步数为0
    if max_height == map[0][0]:
        return [0, 0]

    return [max_height, min_steps]


# 主函数
def main():
    # 输入 n, m, k
    n, m, k = map(int, input().split())

    # 输入山地图
    mountain_map = []
    for i in range(m):
        row = list(map(int, input().split()))
        mountain_map.append(row)

    # 调用BFS方法寻找最高峰和最短步数
    result = bfs(mountain_map, m, n, k)

    # 输出结果
    print(result[0], result[1])


# 调用主函数
if __name__ == "__main__":
    main()

七、JavaScript算法源码

function bfs(map, m, n, k) {
    // 定义四个方向:上、下、左、右
    const dx = [-1, 1, 0, 0];
    const dy = [0, 0, -1, 1];

    // 队列用于BFS存储 [x坐标, y坐标, 当前步数]
    let queue = [];
    let visited = Array.from({ length: m }, () => Array(n).fill(false)); // 记录是否访问过的点
    queue.push([0, 0, 0]); // 从左上角(0,0)出发,步数为0
    visited[0][0] = true;

    let maxHeight = map[0][0]; // 最高峰高度
    let minSteps = 0;          // 最短步数

    while (queue.length > 0) {
        let [x, y, steps] = queue.shift(); // 取出队列的第一个元素

        // 尝试四个方向移动
        for (let i = 0; i < 4; i++) {
            let newX = x + dx[i];
            let newY = y + dy[i];

            // 判断新位置是否在地图范围内
            if (newX >= 0 && newX < m && newY >= 0 && newY < n && !visited[newX][newY]) {
                // 判断高度差是否符合条件
                if (Math.abs(map[newX][newY] - map[x][y]) <= k) {
                    visited[newX][newY] = true;
                    queue.push([newX, newY, steps + 1]);

                    // 更新最高峰和最短步数
                    if (map[newX][newY] > maxHeight) {
                        maxHeight = map[newX][newY];
                        minSteps = steps + 1;
                    } else if (map[newX][newY] === maxHeight && (steps + 1) < minSteps) {
                        minSteps = steps + 1;
                    }
                }
            }
        }
    }

    // 如果最高峰和起点相同(即无法爬山),返回高度和步数为0
    if (maxHeight === map[0][0]) {
        return [0, 0];
    }

    return [maxHeight, minSteps];
}

// 主函数
function main() {
    const input = require('readline-sync');

    // 输入 n, m, k
    let [n, m, k] = input.question("Enter n, m, k: ").split(' ').map(Number);

    // 输入山地图
    let map = [];
    console.log(`Enter the map data (${m} rows of ${n} columns):`);
    for (let i = 0; i < m; i++) {
        map.push(input.question().split(' ').map(Number));
    }

    // 调用BFS方法寻找最高峰和最短步数
    let result = bfs(map, m, n, k);

    // 输出结果
    console.log(`${result[0]} ${result[1]}`);
}

// 调用主函数
main();

八、C算法源码

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MAX 500

// 定义四个方向:上、下、左、右
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};

// 定义队列结构体
typedef struct {
    int x, y, steps;
} QueueNode;

typedef struct {
    QueueNode data[MAX * MAX];
    int front, rear;
} Queue;

// 初始化队列
void initQueue(Queue *q) {
    q->front = 0;
    q->rear = 0;
}

// 队列是否为空
bool isEmpty(Queue *q) {
    return q->front == q->rear;
}

// 入队
void enqueue(Queue *q, int x, int y, int steps) {
    q->data[q->rear].x = x;
    q->data[q->rear].y = y;
    q->data[q->rear].steps = steps;
    q->rear++;
}

// 出队
QueueNode dequeue(Queue *q) {
    return q->data[q->front++];
}

// 广度优先搜索(BFS)算法
void bfs(int map[MAX][MAX], int m, int n, int k, int *maxHeight, int *minSteps) {
    // 初始化队列和访问标记数组
    Queue queue;
    bool visited[MAX][MAX] = {false};
    initQueue(&queue);

    enqueue(&queue, 0, 0, 0); // 从左上角(0, 0)出发,步数为0
    visited[0][0] = true;

    *maxHeight = map[0][0]; // 最高峰高度
    *minSteps = 0;          // 最短步数

    // BFS遍历
    while (!isEmpty(&queue)) {
        QueueNode current = dequeue(&queue);
        int x = current.x;
        int y = current.y;
        int steps = current.steps;

        // 尝试向四个方向移动
        for (int i = 0; i < 4; i++) {
            int newX = x + dx[i];
            int newY = y + dy[i];

            // 判断新位置是否在地图范围内
            if (newX >= 0 && newX < m && newY >= 0 && newY < n && !visited[newX][newY]) {
                // 判断高度差是否符合条件
                if (abs(map[newX][newY] - map[x][y]) <= k) {
                    visited[newX][newY] = true;
                    enqueue(&queue, newX, newY, steps + 1);

                    // 更新最高峰和最短步数
                    if (map[newX][newY] > *maxHeight) {
                        *maxHeight = map[newX][newY];
                        *minSteps = steps + 1;
                    } else if (map[newX][newY] == *maxHeight && (steps + 1) < *minSteps) {
                        *minSteps = steps + 1;
                    }
                }
            }
        }
    }

    // 如果最高峰和起点相同,返回高度和步数为0
    if (*maxHeight == map[0][0]) {
        *maxHeight = 0;
        *minSteps = 0;
    }
}

int main() {
    int n, m, k;
    
    // 输入 n, m, k
    printf("Enter n, m, k: ");
    scanf("%d %d %d", &n, &m, &k);

    int map[MAX][MAX];

    // 输入山地图
    printf("Enter the map data (%d rows of %d columns):\n", m, n);
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            scanf("%d", &map[i][j]);
        }
    }

    int maxHeight, minSteps;

    // 调用BFS方法寻找最高峰和最短步数
    bfs(map, m, n, k, &maxHeight, &minSteps);

    // 输出结果
    printf("%d %d\n", maxHeight, minSteps);

    return 0;
}

九、C++算法源码

#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;

// 定义方向:上、下、左、右
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};

// BFS算法
pair<int, int> bfs(vector<vector<int>>& map, int m, int n, int k) {
    // 队列,用于BFS存储 [x坐标, y坐标, 当前步数]
    queue<pair<pair<int, int>, int>> q;
    vector<vector<bool>> visited(m, vector<bool>(n, false));  // 记录访问过的点
    q.push({{0, 0}, 0});  // 从左上角(0,0)出发,步数为0
    visited[0][0] = true;

    int maxHeight = map[0][0];  // 最高峰高度
    int minSteps = 0;           // 最短步数

    while (!q.empty()) {
        auto current = q.front();
        q.pop();

        int x = current.first.first;
        int y = current.first.second;
        int steps = current.second;

        // 尝试向四个方向移动
        for (int i = 0; i < 4; i++) {
            int newX = x + dx[i];
            int newY = y + dy[i];

            // 检查新位置是否在地图范围内
            if (newX >= 0 && newX < m && newY >= 0 && newY < n && !visited[newX][newY]) {
                // 判断高度差是否符合条件
                if (abs(map[newX][newY] - map[x][y]) <= k) {
                    visited[newX][newY] = true;
                    q.push({{newX, newY}, steps + 1});

                    // 更新最高峰和最短步数
                    if (map[newX][newY] > maxHeight) {
                        maxHeight = map[newX][newY];
                        minSteps = steps + 1;
                    } else if (map[newX][newY] == maxHeight && (steps + 1) < minSteps) {
                        minSteps = steps + 1;
                    }
                }
            }
        }
    }

    // 如果最高峰和起点相同,返回高度和步数为0
    if (maxHeight == map[0][0]) {
        return {0, 0};
    }

    return {maxHeight, minSteps};
}

int main() {
    int n, m, k;

    // 输入 n, m, k
    cout << "Enter n, m, k: ";
    cin >> n >> m >> k;

    vector<vector<int>> map(m, vector<int>(n));

    // 输入山地图
    cout << "Enter the map data (" << m << " rows of " << n << " columns):" << endl;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            cin >> map[i][j];
        }
    }

    // 调用BFS方法寻找最高峰和最短步数
    pair<int, int> result = bfs(map, m, n, k);

    // 输出结果
    cout << result.first << " " << result.second << endl;

    return 0;
}


🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2127658.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql基础——DML

数据操作语言&#xff08;DML&#xff0c;Data Manipulation Language&#xff09; DML语句用于对数据库中的数据进行操作&#xff08;增删改查数据&#xff09;&#xff0c;主要包括&#xff1a; INSERT&#xff1a;向表中插入数据&#xff0c;例如 INSERT INTO table_name …

超简单,3步训练Flux Lora模型,附整合包!

超简单&#xff0c;3步训练Flux Lora模型&#xff0c;附整合包&#xff01; &#x1f389; 12G显存也能炼Flux Lora模型&#xff1f;&#xff01;3步速成&#xff0c;小白也能轻松上手&#xff01; 兄弟们&#xff01;AI绘画领域又迎来了一波革命&#xff01;Flux Lora模型训练…

2024中国500强企业高峰论坛安然大健康分论坛圆满举办!

一场巅峰聚首的风云际会&#xff0c;一次引领未来的行业盛宴。 9月10日至11日&#xff0c;由中国企业联合会、中国企业家协会主办的2024中国500强企业高峰论坛在天津举行&#xff0c;本届高峰论坛以“向‘新’而行、打造更多世界一流企业”为主题&#xff0c;汇集业内知名企业…

利用AI驱动智能BI数据可视化-深度评测Amazon Quicksight(三)

简介 随着生成式人工智能的兴起&#xff0c;传统的 BI 报表功能已经无法满足用户对于自动化和智能化的需求&#xff0c;今天我们将介绍亚马逊云科技平台上的AI驱动数据可视化神器 – Quicksight&#xff0c;利用生成式AI的能力来加速业务决策&#xff0c;从而提高业务生产力。…

【Qt应用】Qt编写简易登录注册界面

目录 引言 一、准备工作 二、设计思路 2.1 登录 2.2 注册 三、登录功能 3.1 创建账号与密码输入框 3.2 设置密码输入框格式 3.2.1 初始 3.2.2 创建一个显示隐藏按钮 3.2.3 信号与槽函数 3.3 创建登录按钮 3.4 创建可选功能 四、注册功能 4.1 账号和密码输入…

【Go】深入探索Go语言中运算符

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

路基边坡自动化监测解决方案

物联网云平台 平台登录--用户登录 输入网址&#xff1a;http://yun.sj2000.org.cn&#xff0c;进入系统登录界面&#xff0c;输入用户名及密码后进入系统平台。 设备详情--设备概览 登录系统平台后&#xff0c;用户可在界面左侧看到系统项目栏和子项目选项&#xff0c;登陆的…

【Python爬虫系列】_018.多线程与多进程

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈 入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈 虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈 PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈 Oracle数…

3. 进阶指南:自定义 Prompt 提升大模型解题能力

怎么判断 Prompt 的好坏&#xff0c;有什么问题有着标准答案么&#xff1f; 答&#xff1a;让大模型求解数学问题。 李宏毅老师的 HW4 正好提到了有关数学问题的 Prompt&#xff0c;所以我决定中间插一篇这样的文章。通过本文你将&#xff1a; 了解各种 Prompt 如何影响大型语言…

基于asp.net电子邮件系统设计与实现

1 引言 1&#xff0e;1 电子邮件介绍 电子邮件(简称E-mai1)又称电子信箱、电子邮政&#xff0c;它是—种用电子手段提供信息交换的通信方式。它是全球多种网络上使用最普遍的一项服务。这种非交互式的通信,加速了信息的交流及数据传送,它是—个简易、快速的方法。通过连接全…

个人用户如何有效利用固态硬盘数据恢复工具

固态硬盘相较于机械硬盘来说更为小巧&#xff0c;所以很多人选择使用固态硬盘来进行数据的存储。这些存储设备都可能会遇到一些意外导致的数据丢失情况。好在现在的科技比较发达&#xff0c;这次我们来聊一聊有哪些固态硬盘数据恢复工具可以解决这个问题吧。 1.福晰数据恢复 …

Sentinel 高级

一、请求限流 1.介绍 处理并发量大时资源耗尽问题 Sentinel的请求限流功能主要体现在对QPS&#xff08;每秒查询率&#xff09;和线程数的控制上。当某个API接口或服务的请求量达到设定的QPS阈值时&#xff0c;Sentinel会触发限流规则&#xff0c;对这些超出阈值的请求进行限…

Selenium自动化测试面试题合集!

1、什么是自动化测试、自动化测试的优势是什么&#xff1f; 通过工具或脚本代替手工测试执行过程的测试都叫自动化测试。 自动化测试的优势&#xff1a; 1、减少回归测试成本 2、减少兼容性测试成本 3、提高测试反馈速度 4、提高测试覆盖率 5、让测试工程师做更有意义的…

官宣:Zilliz 在亚马逊云科技中国区正式开服!

01 Zilliz Cloud 正式上线亚马逊云科技宁夏区服务 9 月 4 日&#xff0c;Zilliz 正式官宣&#xff0c; Zilliz Cloud 正式上线亚马逊云科技在宁夏区的云服务。至此&#xff0c;Zilliz Cloud 已实现全球 5 大云 19 个节点 的全覆盖&#xff0c;成为全球首个提供海内外多云服务的…

读构建可扩展分布式系统:方法与实践01可扩展系统简介

1. 简介 1.1. 在过去20年里&#xff0c;软件系统的规模、复杂性和容量都出现了前所未有的增长 1.2. 代码是容器、数据库、消息传递系统和其他组件的一部分&#xff0c;通过调用API和构建指令&#xff0c;构成你的应用程序 1.3. 可扩展(scalable)是软件工程中用来描述软件系统…

WinCC Professional 变量的线性转换

把PLC中的变量进行线性转换的显示到WinCC Profession画面上&#xff0c;操作步骤如下&#xff1a; 1.在PLC的DB块中创建三个变量&#xff0c;如下所示&#xff1a; 2.在WinCC RT PRO的变量表中也同样创建三个变量&#xff0c;如下所示&#xff1a; 3.对WinCC RT PRO变量表中的…

3个热门、好用、功能强大的C#开源帮助工具类

下面推荐3个热门、好用、功能强大的C#开源帮助工具类。 1、Z.ExtensionMethods Z.ExtensionMethods是由zzzprojects公司开发并维护的一款开源库&#xff0c;为.NET开发人员提供一系列实用的扩展方法&#xff0c;可以减少重复劳动、提高开发效率&#xff0c;支持.NET Framewor…

快递柜电子锁的使用

一、快递柜电子锁的介绍 主要特点&#xff1a; 1、电源需求&#xff1a;该电子锁需要12伏特的直流电源供电&#xff0c;电流限制在2安培&#xff0c;“通电时间≤3S&#xff08;不可长时间通电&#xff09;”&#xff0c;以防止因长时间通电导致的损坏或安全隐患。 2、负荷&am…

DeepGaitV2:显式时间建模,CNN和Transformer在步态任务上的影响

Exploring Deep Models for Practical Gait Recognition 论文链接&#xff1a;http://arxiv.org/abs/2303.03301 代码链接&#xff1a;https://github.com/ShiqiYu/OpenGait 一、摘要 文中提出了一个统一的视角&#xff0c;探讨如何构建用于最先进的户外步态识别的深度模型&…

二层交换机如何工作

在学习之前&#xff0c;先提出几个问题&#xff1a; 二层交换机在哪里&#xff1f;二层交换机是怎么转发数据的&#xff1f;二层交换机如何生成mac地址表&#xff1f;二层交换机怎么去维护mac地址表&#xff1f; 二层交换机&#xff1a;二层交换机是工作在ISO/OSI模型第二层—…