当前位置: 首页 > 面试经验 >

最新华为OD机试真题-K小姐的寻宝之旅(100分)

优质
小牛编辑
87浏览
2024-07-01

最新华为OD机试真题-K小姐的寻宝之旅(100分)

大家好这里是清隆学长 ,一枚热爱算法的程序员

✨ 本系列打算持续跟新华为OD-D卷的三语言AC题解

感谢大家的订阅➕ 和 喜欢

在线评测链接

=> K小姐的寻宝之旅(100分) <=

评测功能需要 =>订阅专栏<= 后联系清隆解锁~

OJ题目截图

K小姐的寻宝之旅

问题描述

K小姐按照地图去寻宝,地图被划分成 行和 列的方格,方格的横纵坐标范围分别是 。在横坐标和纵坐标数位之和不大于 的方格中存在黄金(每个方格中仅存在一克黄金),但横坐标和纵坐标数位之和大于 的方格存在危险不可进入。K小姐从入口 进入,每次只能向上、下、左、右四个方向之一移动一格。请问K小姐最多能获得多少克黄金?

输入格式

输入包含三个正整数 ,分别表示地图的行数、列数以及数位之和的上限,数与数之间用空格隔开。

输出格式

输出一个整数,表示K小姐最多能获得的黄金数量。

样例输入

40 40 18

样例输出

1484

样例输入

4 5 7

样例输出

20

数据范围

题解

本题可以使用深度优先搜索(DFS)来解决。我们从起点 开始,不断地向上、下、左、右四个方向搜索,直到无法继续搜索为止。在搜索过程中,需要注意以下几点:

  1. 如果当前位置越界,或者已经访问过,或者横坐标和纵坐标的数位之和大于 ,则不能进入该位置。
  2. 否则,可以进入该位置,并将获得的黄金数量加
  3. 继续从当前位置向上、下、左、右四个方向搜索。

为了避免重复访问同一个位置,我们可以使用一个 HashSet 来记录已经访问过的位置。此外,为了快速计算横坐标和纵坐标的数位之和,我们可以预处理出一个数位和数组 digitSums,其中 digitSums[i] 表示数字 的数位之和。这样在搜索过程中,就可以直接通过查表的方式获得数位之和,避免了重复计算。

时间复杂度为 ,空间复杂度为

参考代码

  • Python
m, n, k = map(int, input().split())
ans = 0
visited = set()
import sys
sys.setrecursionlimit(10**6)
def dfs(x, y, visited):
    global ans
    if x < 0 or x >= m or y < 0 or y >= n or (x, y) in visited or digit_sum(x) + digit_sum(y) > k:
        return
    visited.add((x, y))
    ans += 1
    for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
        dfs(x + dx, y + dy, visited)

def digit_sum(num):
    return sum(map(int, str(num)))

dfs(0, 0, visited)
print(ans)
  • Java
import java.util.HashSet;
import java.util.Scanner;

public class Main {
    static int m, n, k;
    static int ans = 0;
    static HashSet<Integer> visited = new HashSet<>();
    static int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    static int[] digitSums;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        m = sc.nextInt();
        n = sc.nextInt(); 
        k = sc.nextInt();
        digitSums = new int[Math.max(m, n)];
        for (int i = 0; i < digitSums.length; i++) {
            digitSums[i] = digitSum(i);
        }
        dfs(0, 0);
        System.out.println(ans);
    }

    static void dfs(int x, int y) {
        if (x < 0 || x >= m || y < 0 || y >= n || visited.contains(x * n + y) || digitSums[x] + digitSums[y] > k) {
            return;
        }
        visited.add(x * n + y);
        ans++;
        for (int[] dir : dirs) {
            dfs(x + dir[0], y + dir[1]);
        }
    }

    static int digitSum(int num) {
        int sum = 0;
        while (num > 0) {
            sum += num % 10;
            num /= 10;
        }
        return sum;
    }
}
  • Cpp
#include <iostream>
#include <unordered_set>
using namespace std;

int m, n, k;
int ans = 0;
unordered_set<int> visited;
int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int *digitSums;

void dfs(int x, int y) {
    if (x < 0 || x >= m || y < 0 || y >= n || visited.count(x * n + y) || digitSums[x] + digitSums[y] > k) {
        return;
    }
    visited.insert(x * n + y);
    ans++;
    for (auto &dir : dirs) {
        dfs(x + dir[0], y + dir[1]);
    }
}

int digitSum(int num) {
    int sum = 0;
    while (num > 0) {
        sum += num % 10;
        num /= 10;
    }
    return sum;
}

int main() {
    cin >> m >> n >> k;
    digitSums = new int[max(m, n)];
    for (int i = 0; i < max(m, n); i++) {
        digitSums[i] = digitSum(i);
    }
    dfs(0, 0);
    cout << ans << endl;
    delete[] digitSums;
    return 0;
}
#华为##华为OD##华为OD机试算法题库##笔试##秋招#
 类似资料: