2025华为od机试真题B卷【小明减肥】C++实现

目录

题目

思路

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

#include <iostream>
#include <vector>

using namespace std;

class Solution {
private:
    /**
     * 深度优先搜索辅助函数
     * @param start 当前考虑的运动索引
     * @param remainingK 还需要选择的运动数量
     * @param currentSum 当前已选运动的卡路里和
     * @param n 运动总数
     * @param t 目标卡路里和
     * @param calories 卡路里数组
     * @return 满足条件的组合数量
     */
    int dfs(int start, int remainingK, int currentSum,
            int n, int t, const vector<int>& calories) {
        // 基础情况:已经选够k个运动
        if (remainingK == 0) {
            return currentSum == t ? 1 : 0;
        }
        
        // 如果剩余的运动不够选或者已经超出目标值,返回0
        if (start >= n || remainingK > n - start || currentSum > t) {
            return 0;
        }
        
        // 不选择当前运动
        int count = dfs(start + 1, remainingK, currentSum, n, t, calories);
        // 选择当前运动
        count += dfs(start + 1, remainingK - 1,
                    currentSum + calories[start], n, t, calories);
        
        return count;
    }

public:
    /**
     * 计算满足条件的运动组合数量
     * @param n 运动总数
     * @param t 目标卡路里和
     * @param k 需要选择的运动数量
     * @param calories 每个运动的卡路里向量
     * @return 满足条件的组合数量
     */
    int countExerciseCombinations(int n, int t, int k, vector<int>& calories) {
        // 输入验证
        if (!(0 < n && n < 10 && t > 0 && 0 < k && k <= n)) {
            return 0;
        }
        
        return dfs(0, k, 0, n, t, calories);
    }
};

int main() {
    int n, t, k;
    // 读取输入
    cin >> n >> t >> k;
    
    vector<int> calories(n);
    for (int i = 0; i < n; i++) {
        cin >> calories[i];
    }
    
    Solution solution;
    // 输出结果
    cout << solution.countExerciseCombinations(n, t, k, calories) << endl;
    
    return 0;
}

【华为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、付费专栏及课程。

余额充值