【100%通过率】2025华为od机试真题B卷【小明减肥】Python实现

目录

题目

思路

Code


题目

小明有n个可选运动,每个运动有对应卡路里,想选出其中k个运动且卡路里和为t。k,t,n都是给定的。求出可行解数量
输入描述
第一行输入n t k
第二行输入 每个运动的卡路里 按照空格进行分割
备注
0<n<10
t>0,0<k<=n
每个运动量的卡路里>0
输出描述
求出可行解数量

示例1:

输入

4 3 2
1 1 2 3

输出

2

说明
可行解为2,选取{0,2},{1,2}两种方式。

思路

1. 问题分析

1.1 题目理解

输入内容的详细解释:

  • 第一行包含三个整数:n(运动总数)、t(目标卡路里和)、k(需要选择的运动数量)
  • 第二行包含n个整数,表示每个运动的卡路里值,以空格分隔

输出要求的具体说明:

  • 输出一个整数,表示满足条件的组合数量
  • 条件:从n个运动中选择k个,使得这k个运动的卡路里和等于t

约束条件的整理:

  • 0 < n < 10(运动总数小于10)
  • t > 0(目标卡路里和为正数)
  • 0 < k <= n(选择的运动数量大于0且不超过总运动数)
  • 每个运动的卡路里值均为正数

1.2 问题建模

将问题转化为具体的数据结构:

  • 输入的运动卡路里可以用数组表示
  • 本质是一个组合问题,需要从n个数中选择k个数,使其和为t

确定需要使用的算法类型:

  • 这是一个组合计数问题
  • 可以使用回溯法(DFS)或动态规划来解决

分析问题的数学模型:

  • 组合数学中的子集选择问题
  • 需要满足两个条件:
  1. 选择恰好k个元素
  1. 这k个元素的和恰好为t

2. 解题思路

2.1 算法选择

最优算法:

  • 使用回溯法(DFS)
  • 原因:问题规模较小(n<10),回溯法的性能足够好,且实现直观

时间和空间复杂度分析:

  • 时间复杂度:O(C(n,k)),其中C(n,k)是组合数
  • 空间复杂度:O(k),递归栈的深度

2.2 核心数据结构

主要数据结构的选择理由:

  • 使用数组存储输入的卡路里值
  • 使用递归函数的参数来追踪当前状态

数据结构的具体实现方式:

  • 一维数组存储卡路里值
  • 递归函数参数包含:当前位置、已选数量、当前和

数据结构的操作复杂度:

  • 数组访问:O(1)
  • 递归调用:每层复杂度O(1)

2.3 关键算法步骤

算法的详细步骤说明:

  1. 读取输入参数n、t、k和卡路里数组
  1. 实现DFS函数,包含以下参数:
  • 当前考虑的位置
  • 已经选择的运动数量
  • 当前卡路里和
  1. DFS过程中:
  • 对当前位置的运动进行选择或不选择
  • 记录满足条件的解的数量

每个步骤的作用和原理:

  • 选择当前运动:更新已选数量和卡路里和
  • 不选择当前运动:直接考虑下一个运动
  • 递归终止条件:已选够k个运动或达到数组末尾

Code

def count_exercise_combinations(n: int, t: int, k: int, calories: list) -> int:
    """
    计算满足条件的运动组合数量
    :param n: 运动总数
    :param t: 目标卡路里和
    :param k: 需要选择的运动数量
    :param calories: 每个运动的卡路里列表
    :return: 满足条件的组合数量
    """
    # 输入验证
    if not (0 < n < 10 and t > 0 and 0 < k <= n):
        return 0
    if any(cal <= 0 for cal in calories):
        return 0
    
    def dfs(start: int, remaining_k: int, current_sum: int) -> int:
        """
        深度优先搜索函数
        :param start: 当前考虑的运动索引
        :param remaining_k: 还需要选择的运动数量
        :param current_sum: 当前已选运动的卡路里和
        :return: 满足条件的组合数量
        """
        # 基础情况:已经选够k个运动
        if remaining_k == 0:
            return 1 if current_sum == t else 0
            
        # 如果剩余的运动不够选或者已经超出目标值,返回0
        if start >= n or remaining_k > n - start or current_sum > t:
            return 0
            
        # 不选择当前运动
        count = dfs(start + 1, remaining_k, current_sum)
        # 选择当前运动
        count += dfs(start + 1, remaining_k - 1, current_sum + calories[start])
        
        return count
    
    return dfs(0, k, 0)

# 测试代码
if __name__ == "__main__":
    # 读取输入
    n, t, k = map(int, input().split())
    calories = list(map(int, input().split()))
    # 输出结果
    print(count_exercise_combinations(n, t, k, calories))

【华为od机试真题Python+JS+Java合集】【超值优惠】:Py/JS/Java合集

【华为od机试真题Python】:Python真题题库

【华为od机试真题JavaScript】:JavaScript真题题库

【华为od机试真题Java】:Java真题题库

【华为od机试真题C++】:C++真题题库

【华为od机试真题C语言】:C语言真题题库

【华为od面试手撕代码题库】:面试手撕代码题库

【华为od机试面试交流群:830285880】

华为OD机试:二本院校有机会吗?
有机会,但不大,大神除外!机考分数越高越好,所以需要提前刷题。机考通过后,如果没有收到面试邀请,也不要着急,非目标院校面试邀请发的时间比较晚。非目标院校今年有点难,机试至少要考到350分,所以需要疯狂刷题,华为OD机考是有题库的,最好在考前完所有题库题目。华为OD机试:跨专业可以参加华为OD可以,但是如果你的本科院校比较差,上岸概率不大。华为OD机试:华为OD简历被锁定机试通过,性格测试也通过,但是没人联系面试,发现简历被锁定。此时需要主动去联系HR。让他帮助你查询原因。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MISAYAONE

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值