题目描述:
小华按照地图去寻宝,地图上被划分成 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
输出描述:
输出小华最多能获得多少克黄金
示例1:
输入
40 40 18
输出
1484
说明:当k=18时,小华能够进入方格(10, 10),因为1+0+1+0=2<=18;
同理,小华不能够进入方格(36, 38),因为3+6+3+8=20?
示例2:
输入
4 5 7
输出
20
C++源码:
#include <iostream>
#include <vector>
using namespace std;
const int MAX = 51;
int m, n, k;
int grid[MAX][MAX]; // 用于记录每个格子是否有黄金,1表示有黄金,0表示没有或已访问
int dx[] = { -1, 0, 1, 0 }; // 上下左右四个方向的横坐标偏移量
int dy[] = { 0, 1, 0, -1 }; // 上下左右四个方向的纵坐标偏移量
bool isValidCell(int x, int y) {
// 判断当前坐标是否在地图范围内
return x >= 0 && x < n && y >= 0 && y < m;
}
// 计算数字的数位之和
int digitSum(int num) {
int sum = 0;
while (num) {
sum += num % 10;
num /= 10;
}
return sum;
}
void initializeGrid() {
// 根据题目条件初始化地图,只有坐标数位之和不大于k的格子才初始化为有黄金
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (digitSum(i) + digitSum(j) <= k) {
grid[i][j] = 1; // 满足条件的格子设为有黄金
}
else {
grid[i][j] = 0; // 其他格子默认无黄金或视为障碍
}
}
}
}
int dfs(int x, int y) {
// 深度优先搜索获取最多黄金数量
if (!isValidCell(x, y)) return 0; // 不安全的位置返回0
if (grid[x][y] == 0) return 0; // 已访问过或没有黄金的位置返回0
grid[x][y] = 0; // 标记为已访问
int maxGold = 0;
for (int i = 0; i < 4; ++i) {
int newX = x + dx[i];
int newY = y + dy[i];
maxGold = max(maxGold, dfs(newX, newY)); // 递归探索四周并取最大值
}
return maxGold + 1; // 加上当前位置的黄金
}
int main() {
cin >> m >> n >> k;
initializeGrid(); // 根据k值初始化地图
cout << dfs(0, 0) << endl; // 从(0,0)开始搜索
system("pause");
return 0;
}