华为OD机试_2025 B卷_小华地图寻宝(Python,100分)(附详细解题思路)

文章目录

题目描述

小华按照地图去寻宝,地图上被划分成 m 行和 n 列的方格,横纵坐标范围分别是 [0, n-1] 和 [0, m-1]。

在横坐标和纵坐标的数位之和不大于 k 的方格中存在黄金(每个方格中仅存在一克黄金),但横坐标和纵坐标数位之和大于 k 的方格存在危险不可进入。小华从入口 (0,0) 进入,任何时候只能向左,右,上,下四个方向移动一格。

请问小华最多能获得多少克黄金?

输入描述

坐标取值范围如下:

0 ≤ m ≤ 50

0 ≤ n ≤ 50

k 的取值范围如下:

0 ≤ k ≤ 100

输入中包含3个字数,分别是m, n, k

输出描述

输出小华最多能获得多少克黄金

用例

|----|----------|
| 输入 | 40 40 18 |
| 输出 | 1484 |
| 说明 | 无 |

|----|-------|
| 输入 | 5 4 7 |
| 输出 | 20 |
| 说明 | 无 |

小华寻宝问题:简单直观的BFS解法

核心解题思路

关键问题分析

小华需要从起点 (0,0) 出发,访问所有满足条件的格子:

  1. 只能进入坐标数位之和 ≤ k 的格子
  2. 只能在相邻的满足条件的格子间移动
  3. 每个满足条件的格子有1克黄金

简单解法:广度优先搜索(BFS)

使用BFS可以高效解决网格遍历问题:

  1. 从起点 (0,0) 开始
  2. 检查当前格子是否满足条件
  3. 向四个方向扩展
  4. 统计访问过的所有满足条件的格子数量

为什么BFS适合?

  1. 保证访问所有可达格子:BFS按层遍历,不会遗漏
  2. 避免重复访问:使用标记数组记录已访问格子
  3. 高效实现:网格最大50×50=2500个格子,BFS完全可行
  4. 直观易懂:模拟小华实际移动过程

算法步骤详解

1. 数位之和计算

python 复制代码
def digit_sum(i, j):
    """计算坐标(i,j)的数位之和"""
    total = 0
    for num in [i, j]:
        while num:
            total += num % 10
            num //= 10
    return total

2. 输入处理

python 复制代码
m, n, k = map(int, input().split())

3. 特殊情况处理

  • 网格为空时直接返回0
  • 起点不满足条件时返回0

4. BFS核心

python 复制代码
from collections import deque

# 初始化
visited = [[False] * n for _ in range(m)]
queue = deque()
gold_count = 0

# 起点检查
if digit_sum(0, 0) <= k:
    queue.append((0, 0))
    visited[0][0] = True

# BFS主循环
while queue:
    i, j = queue.popleft()
    gold_count += 1  # 获得黄金
    
    # 四个方向:上、下、左、右
    for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
        ni, nj = i + dx, j + dy
        # 检查新坐标是否有效
        if 0 <= ni < m and 0 <= nj < n:
            # 检查是否访问过且满足条件
            if not visited[ni][nj] and digit_sum(ni, nj) <= k:
                visited[ni][nj] = True
                queue.append((ni, nj))

5. 输出结果

python 复制代码
print(gold_count)

完整代码实现

python 复制代码
from collections import deque

def digit_sum(i, j):
    """计算坐标(i,j)的数位之和"""
    total = 0
    for num in [i, j]:
        while num:
            total += num % 10
            num //= 10
    return total

# 输入处理
m, n, k = map(int, input().split())

# 处理网格为空的情况
if m == 0 or n == 0:
    print(0)
    exit()

# 初始化BFS数据结构
visited = [[False] * n for _ in range(m)]
queue = deque()
gold_count = 0

# 检查起点(0,0)
if digit_sum(0, 0) <= k:
    queue.append((0, 0))
    visited[0][0] = True

# BFS主循环
while queue:
    i, j = queue.popleft()
    gold_count += 1  # 获得当前格子的黄金
    
    # 遍历四个方向:上、下、左、右
    directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
    for dx, dy in directions:
        ni, nj = i + dx, j + dy  # 新坐标
        
        # 检查新坐标是否在网格内
        if 0 <= ni < m and 0 <= nj < n:
            # 检查是否未访问且满足条件
            if not visited[ni][nj] and digit_sum(ni, nj) <= k:
                visited[ni][nj] = True
                queue.append((ni, nj))

# 输出结果
print(gold_count)

示例验证

用例1:输入 5 4 7 → 输出 20

  • 网格大小:5行4列(20个格子)
  • 所有格子数位之和 ≤ 7(最大为4+3=7)
  • BFS会访问所有20个格子
  • 输出20正确

用例2:输入 40 40 18 → 输出 1484

  • BFS遍历所有满足条件的格子
  • 计算结果为1484,符合题目要求

BFS执行过程

  1. 初始化:起点(0,0)入队
  2. 循环开始:出队(0,0),黄金+1
  3. 扩展邻居:(0,1)、(1,0)入队
  4. 继续出队:处理(0,1),扩展邻居
  5. 层层扩展:直到所有可达格子被访问
  6. 结束条件:队列为空

关键算法点

1. 方向处理

python 复制代码
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]

使用元组表示四个移动方向:

  • (0,1):向右移动
  • (0,-1):向左移动
  • (1,0):向下移动
  • (-1,0):向上移动

2. 访问标记

python 复制代码
visited = [[False] * n for _ in range(m)]
  • 创建二维数组记录访问状态
  • 避免重复访问,提高效率

3. 边界检查

python 复制代码
if 0 <= ni < m and 0 <= nj < n:

确保新坐标在网格范围内

边界情况处理

  1. 网格为空m == 0 or n == 0 时直接输出0
  2. 起点不满足条件:k < 0 时输出0(但k≥0,起点数位和=0,所以不会发生)
  3. 孤立区域:BFS只访问连通区域,自动处理孤立区

为什么BFS比DFS更合适?

  1. 非递归实现:避免递归深度过大
  2. 更少内存占用:队列比调用栈更节省空间
  3. 层序访问:更符合网格遍历特点
  4. 避免堆栈溢出:网格最大2500个点,DFS递归深度可能达2500级

总结与思考

通过这个解法,我们学习到:

  1. BFS的基本框架
    • 队列初始化
    • 访问标记
    • 方向扩展
  2. 网格问题的处理技巧
    • 方向数组简化移动
    • 边界检查确保安全
    • 访问标记避免重复
  3. 问题分析能力
    • 识别连通区域特性
    • 选择合适遍历算法
    • 处理边界条件

BFS解法时间复杂度 O(m×n),空间复杂度 O(m×n),在题目约束下完全可行。代码简洁直观,适合初学者理解和实现。

小技巧:网格遍历问题优先考虑BFS,它提供了一种系统化、可预测的访问顺序,确保不会遗漏任何可达点。

相关推荐
杜子不疼.9 小时前
【C++】玩转模板:进阶之路
java·开发语言·c++
万粉变现经纪人9 小时前
如何解决 pip install 安装报错 ImportError: cannot import name ‘xxx’ from ‘yyy’ 问题
python·selenium·测试工具·flask·scikit-learn·fastapi·pip
深栈9 小时前
机器学习:线性回归
人工智能·pytorch·python·机器学习·线性回归·sklearn
simon_skywalker9 小时前
第三章 字典与集合
python
gc_229910 小时前
学习Python中Selenium模块的基本用法(18:使用ActionChains操作鼠标)
python·selenium
拾忆,想起10 小时前
AMQP协议深度解析:消息队列背后的通信魔法
java·开发语言·spring boot·后端·spring cloud
Lululaurel10 小时前
从静态图表到交互叙事:数据可视化的新范式与实现
python·信息可视化·数据分析·matplotlib·数据可视化
蒋星熠10 小时前
TensorFlow与PyTorch深度对比分析:从基础原理到实战选择的完整指南
人工智能·pytorch·python·深度学习·ai·tensorflow·neo4j
qq_3404740210 小时前
0.1 tensorflow例1-梯度下降法
人工智能·python·tensorflow
紫钺-高山仰止11 小时前
【Pyzmq】python 跨进程线程通信 跨平台跨服务器通信
服务器·python·github