小华按照地图去寻宝,地图上被划分成 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 |
说明 | 无 |
小华需要从起点 (0,0) 出发,访问所有满足条件的格子:
使用BFS可以高效解决网格遍历问题:
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())
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))
print(gold_count)
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
用例2:输入 40 40 18 → 输出 1484
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
使用元组表示四个移动方向:
visited = [[False] * n for _ in range(m)]
if 0 <= ni < m and 0 <= nj < n:
确保新坐标在网格范围内
m == 0 or n == 0
时直接输出0通过这个解法,我们学习到:
BFS解法时间复杂度 O(m×n),空间复杂度 O(m×n),在题目约束下完全可行。代码简洁直观,适合初学者理解和实现。
小技巧:网格遍历问题优先考虑BFS,它提供了一种系统化、可预测的访问顺序,确保不会遗漏任何可达点。