
✅创作者:陈书予
 🎉个人主页:陈书予的个人主页
 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区
 🌟专栏地址: Java华为OD机试真题(2022&2023) 
文章目录
- 1. 题目描述
 - 2. 输入描述
 - 3. 输出描述
 - 4. Java算法源码
 - 5. 测试
 - 6.解题思路
 
1. 题目描述
给你一个整数M和数组N,N中的元素为连续整数,要求根据N中的元素组装成新的数组R。
组装规则:
R中元素总和加起来等于M;
 R中的元素可以从N中重复选取;
 R中的元素最多只能有1个不在N中,且比N中的数字都要小(不能为负数)
2. 输入描述
第一行输入是连续数组N,采用空格分隔;
 第二行输入数字M;
3. 输出描述
输出的是组装办法数量,int类型。
补充:
 1 <= N.length <= 30
 1 <= N.length <= 1000
4. Java算法源码
/**
 * 给你一个整数M和数组N
 * 
 * N中的元素为连续整数,要求根据N中的元素组装成新的数组R
 * 
 * 1、R中元素总和加起来等于M
 * 2、R中的元素可以从N中重复选取
 * 3、R中的元素最多只能有1个不在N中,且比N中的数字都要小(不能为负数)
 */
// 组装办法数量
private static int sum = 0;
private static int min = Integer.MAX_VALUE;
public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    // 连续数组N,采用空格分隔
    String[] N = sc.nextLine().split(" ");
    // 新数组R数字之和 = 数字M
    int M = sc.nextInt();
    // 数组N
    int[] arr = new int[N.length];
    for (int i = 0; i < N.length; i++) {
        arr[i] = Integer.parseInt(N[i]);
        // 取数组N的最小值
        min = Math.min(min, arr[i]);
    }
    get(0, arr, M, 0);
    System.out.println(sum);
}
/**
 *
 * @param idx
 * @param n 连续数组N,采用空格分隔
 * @param M 新数组R数字之和 = 数字M
 * @param rSum 新数组R数字之和
 */
public static void get(int idx, int[] n, int M, int rSum) {
    if (rSum == M) {
        sum++;
        return;
    }
    if (rSum > M) {
        return;
    }
    /**
     * R中的元素最多只能有1个不在N中,且比N中的数字都要小
     *
     * 新数组R数字之和 - 当前新数组R数字之和 <= 取数组N的最小值
     */
    if (M - rSum <= min - 1) {
        sum++;
        return;
    }
    for (int i = idx; i < n.length; i++) {
        get(i, n, M, rSum + n[i]);
    }
}
 
5. 测试

6.解题思路
 
- 读取输入的连续数组 
N和数字M。 - 将连续数组 
N转换为整数数组arr。 - 初始化变量 
sum表示组装办法数量,初始值为 0。 - 初始化变量 
min表示数组N中的最小值,初始值为正无穷大。 - 遍历数组 
N,将每个元素转换为整数,并更新min的值为数组N的最小值。 - 调用递归函数 
get(0, arr, M, 0),计算组装办法数量。 - 在递归函数 
get中,如果当前新数组R的数字之和等于M,则将sum加 1。 - 如果当前新数组 
R的数字之和大于M,则返回。 - 如果 
M - rSum <= min - 1,表示剩余的数字和已经小于等于min - 1,则将sum加 1,并返回。 - 否则,从当前索引 
idx开始遍历数组N,递归调用get函数,更新索引idx和新数组R的数字之和rSum。 - 最后,输出组装办法数量 
sum。

 



















