返回目录
题目描述
小华按照地图去寻宝,地图上被划分成 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
输出描述
输出小华最多能获得多少克黄金
示例:
输入 | 5 4 7 |
---|---|
输出 | 20 |
说明 | 如图每个单元格中的数位之和均不大于7,都是符合要求的,所以可以最多可获得20克黄金 |
题目解析
本题题目描述有些歧义
在横坐标和纵坐标的数位之和不大于 k 的方格中存在黄金(每个方格中仅存在一克黄金)
和
但横坐标和纵坐标之和大于 k 的方格存在危险不可进入
这两句话有点矛盾,所谓横坐标和纵坐标的数位之和,比如:
- 横坐标是10,那么横坐标的数位和 = 1 + 0 = 1
- 纵坐标是21,那么纵坐标的数位和 = 2 + 1 = 3
- 横坐标和纵坐标的数位之和 = 1 + 3 = 4
但是横坐标和纵坐标之和
- 横坐标是10,纵坐标是21,横坐标和纵坐标之和 = 10 + 21 = 31
Python算法源码
import sys
class GoldMine:
def __init__(self, m, n, k):
"""
初始化金矿类对象。
参数:
m (int): 金矿行数。
n (int): 金矿列数。
k (int): 数位和的限制。
"""
self.m = m
self.n = n
self.k = k
self.ans = 0
self.visited = set()
self.offsets = ((-1, 0), (1, 0), (0, -1), (0, 1))
self.digitSums = [0] * max(m, n)
for i in range(len(self.digitSums)):
num = i
while num > 0:
self.digitSums[i] += num % 10
num //= 10
def dfs(self, x, y):
"""
深度优先搜索金矿。
参数:
x (int): 当前位置的行坐标。
y (int): 当前位置的列坐标。
"""
if x < 0 or x >= self.m or y < 0 or y >= self.n:
return
if self.digitSums[x] + self.digitSums[y] > self.k:
return
pos = x * self.n + y
if pos in self.visited:
return
self.visited.add(pos)
self.ans += 1
for offsetX, offsetY in self.offsets:
newX = x + offsetX
newY = y + offsetY
self.dfs(newX, newY)
def find_gold(self):
"""
寻找金矿的入口函数。
返回:
int: 可采集的金矿数量。
"""
self.dfs(0, 0)
return self.ans
# 输入获取
m, n, k = map(int, input().split())
# 算法入口
gold_mine = GoldMine(m, n, k)
print(gold_mine.find_gold())
C算法源码
#include <stdio.h>
// 全局变量
int ans = 0; // 记录结果
int visited[5000]; // 记录已访问的位置,避免重复计算
int offsets[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // 上下左右偏移量
int digitSums[5000]; // 数位和数组
// 深度优先搜索函数
void dfs(int x, int y, int m, int n, int k) {
// 如果位置越界,则返回
if (x < 0 || x >= m || y < 0 || y >= n)
return;
// 如果横坐标和纵坐标对应的数位和之和超过k,则返回
if (digitSums[x] + digitSums[y] > k)
return;
int pos = x * n + y;
// 如果位置已经访问过,则返回
if (visited[pos])
return;
// 将位置标记为已访问
visited[pos] = 1;
// 增加结果计数
ans++;
// 继续在上下左右四个方向进行深度优先搜索
for (int i = 0; i < 4; i++) {
int newX = x + offsets[i][0];
int newY = y + offsets[i][1];
dfs(newX, newY, m, n, k);
}
}
int main() {
// 输入
int m, n, k;
scanf("%d %d %d", &m, &n, &k);
// 初始化数位和数组
for (int i = 0; i < (m > n ? m : n); i++) {
int num = i;
while (num > 0) {
digitSums[i] += num % 10;
num /= 10;
}
}
// 执行深度优先搜索
dfs(0, 0, m, n, k);
// 输出结果
printf("%d\n", ans);
return 0;
}
Java算法源码
import java.util.Scanner;
public class Main {
// 记录题解
static int ans = 0;
// 记录已访问过的位置,避免重复统计
static int[] visited;
// 上下左右偏移量
static int[][] offsets = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
// 数位和数组
static int[] digitSums;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();
int n = scanner.nextInt();
int k = scanner.nextInt();
// digitSums数组的索引是原始数,值是原始数对应的数位和
int maxSize = Math.max(m, n);
digitSums = new int[maxSize];
for (int i = 0; i < maxSize; i++) {
int num = i;
while (num > 0) {
digitSums[i] += num % 10;
num /= 10;
}
}
// visited数组记录已访问过的位置,避免重复统计
visited = new int[m * n];
dfs(0, 0, m, n, k);
System.out.println(ans);
}
static void dfs(int x, int y, int m, int n, int k) {
// 如果对应位置越界,则不能进入
if (x < 0 || x >= m || y < 0 || y >= n) {
return;
}
// 如果对应位置已横坐标、纵坐标的数位和之和超过了k,则不能进入
if (digitSums[x] + digitSums[y] > k) {
return;
}
// 如果对应位置已访问过,则不能进入
int pos = x * n + y;
if (visited[pos] == 1) {
return;
}
// 否则可以进入
visited[pos] = 1;
// 且获得黄金
ans += 1;
// 继续遍历上、下、左、右方向上的新位置继续深搜
for (int i = 0; i < 4; i++) {
int newX = x + offsets[i][0];
int newY = y + offsets[i][1];
dfs(newX, newY, m, n, k);
}
}
}
6 条评论
m,n,yuzhi = map(int,input().split())
visited = set() # 记录计算过的坐标
ans = 0
digitSum = [0]*max(m,n)
position = [(0,1),(0,-1),(1,0),(-1,0)]
for i in range(len(digitSum)): # 初始化一个数组,记录各个int的数位之和,比如123对应1+2+3=6
j = i
while j > 0:
digitSum[i] += j % 10
j //= 10
print(digitSum)
def dnf(x,y): # 深度优先,递归
if not(0 yuzhi: # 分位之和大于yuzhi
return
global ans
ans += 1
for newX, newY in position:
newX = x + newX
newY = y + newY
dnf(newX,newY)
dnf(0,0)
print(ans)
[...]2024 C卷 100分序号题目知 识 点难易程度1密码输入检测数据结构/栈☆☆☆2分配土地几何问题☆☆☆3找座位逻辑分析☆☆☆4智能成绩表动态条件分析☆☆☆5内存冷热标记多条件排序☆☆☆6螺旋数字矩阵逻辑分析☆☆☆7围棋的气逻辑分析☆☆☆8分割平衡字符串逻辑分析☆☆☆9机器人搬砖二分法☆☆☆10转盘寿司数据结构/栈/单调栈☆☆☆11小明找位置二分法☆☆☆12提取字符串的最长合法简单数学表达式双指[...]
[...]2024 C卷 100分序号题目知 识 点难易程度1密码输入检测数据结构/栈☆☆☆2分配土地几何问题☆☆☆3找座位逻辑分析☆☆☆4智能成绩表动态条件分析☆☆☆5内存冷热标记多条件排序☆☆☆6螺旋数字矩阵逻辑分析☆☆☆7围棋的气逻辑分析☆☆☆8分割平衡字符串逻辑分析☆☆☆9机器人搬砖二分法☆☆☆10转盘寿司数据结构/栈/单调栈☆☆☆11小明找位置二分法☆☆☆12提取字符串的最长合法简单数学表达式双指[...]
[...]2024 C卷 100分序号题目知 识 点难易程度1密码输入检测数据结构/栈☆☆☆2分配土地几何问题☆☆☆3找座位逻辑分析☆☆☆4智能成绩表动态条件分析☆☆☆5内存冷热标记多条件排序☆☆☆6螺旋数字矩阵逻辑分析☆☆☆7围棋的气逻辑分析☆☆☆8分割平衡字符串逻辑分析☆☆☆9机器人搬砖二分法☆☆☆10转盘寿司数据结构/栈/单调栈☆☆☆11小明找位置二分法☆☆☆12提取字符串的最长合法简单数学表达式双指[...]
[...]2024 C卷 100分序号题目知 识 点难易程度1密码输入检测数据结构/栈☆☆☆2分配土地几何问题☆☆☆3找座位逻辑分析☆☆☆4智能成绩表动态条件分析☆☆☆5内存冷热标记多条件排序☆☆☆6螺旋数字矩阵逻辑分析☆☆☆7围棋的气逻辑分析☆☆☆8分割平衡字符串逻辑分析☆☆☆9机器人搬砖二分法☆☆☆10转盘寿司数据结构/栈/单调栈☆☆☆11小明找位置二分法☆☆☆12提取字符串的最长合法简单数学表达式双指[...]
[...]真题目录序号题目知 识 点难易程度1密码输入检测数据结构/栈☆☆☆2分配土地几何问题☆☆☆3找座位逻辑分析☆☆☆4智能成绩表动态条件分析☆☆☆5内存冷热标记多条件排序☆☆☆6螺旋数字矩阵逻辑分析☆☆☆ 围棋的气逻辑分析☆☆☆ 分割平衡字符串逻辑分析☆☆☆ 机器人搬砖二分法☆☆☆ 转盘寿司数据结构/栈/单调栈☆☆☆ 小明找位置二分法☆☆☆ 提取字符串的最长合法简单数学表达式双指针☆☆☆☆ 掌握的单词[...]