2023华为OD机试真题-组装新的数组(JAVA、Python、C++)

题目描述:
给你一个整数M和数组N,N中的元素为连续整数,要求根据N中的元素组装成新的数组R,组装规则:
1.R中元素总和加起来等于M
1.R中的元素可以从N中重复选取
2.R中的元素最多只能有1个不在N中,且比N中的数字都要小(不能为负数)
请输出:数组R一共有多少组装办法
输入描述:
第一行输入是连续数组N,采用空格分隔
第二行输入数字M
输出描述:
输出的是组装办法数量,int类型
补充说明:
1 <= N.length <= 30
1 <= N.length <= 1000
 收起
示例1
输入:
2
5
输出:
1
说明:
只有1种组装办法,就是[2,2,1]
示例2
输入:
2 3
5
输出:
2
说明:
一共2种组装办法,分别是[2,2,1],[2,3]
 

import java.util.Scanner;
 
public class Main {
    static int ans = 0;
    static int min = Integer.MAX_VALUE;
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String [] s = in.nextLine().split(" ");
        int M = in.nextInt();
        int [] n = new int[s.length];
        for (int i = 0; i < s.length; i++) {
           n[i] = Integer.parseInt(s[i]);
           min = Math.min(min,n[i]);
        }
        dfs(0,n,M,0);
        System.out.println(ans);
    }
 
    public static void dfs(int idx,int [] n, int value, int currV){
        if(currV==value){
            ans++;
            return;
        }
        if(currV>value){
            return;
        }
        if(value-currV<=min-1){
            ans++;
            return;
        }
 
        for (int i = idx; i < n.length; i++) {
            //选这个数字
            dfs(i, n,value,currV+n[i]);
        }
    }
}
N = list(map(int, input().split()))
M = int(input())
N.sort()
length = len(N)
count = 0
# lis = [0] * length
# reach_max = []
# for i in range(length):
#     reach_max.append(M // N[i])
# pos = len(lis) - 1
# while True:
#     if pos == -1:
#         break
#     while  pos < length-1 and lis[pos] <= reach_max[pos]:
#         sum_res = 0
#         for i in range(length):
#             sum_res += N[i] * lis[i]
#         delta = M - sum_res
#         if 0 <= delta < N[0]:
#             count += 1
#         pos -= 1
if length == 1:
    count = 1
elif length == 2:
    count = 2
elif length == 3:
    for i in range(0, M // N[0] + 1):
        for j in range(0, M // N[1] + 1):
            for k in range(0, M // N[2] + 1):
                sum_res = N[0] * i + N[1] * j + N[2] * k
                delta = M - sum_res
                if delta < 0:
                    break  
                if  0 <= delta < N[0]:
                    count += 1
elif length == 4:
    for i in range(0, M // N[0] + 1):
        for j in range(0, M // N[1] + 1):
            for k in range(0, M // N[2] + 1):
                for a in range(0, M // N[3] + 1):
                    sum_res = N[0] * i + N[1] * j + N[2] * k + N[3] * a
                    delta = M - sum_res
                    if delta < 0:
                        break  
                    if  0 <= delta < N[0]:
                        count += 1
elif length == 5:
    for i in range(0, M // N[0] + 1):
        for j in range(0, M // N[1] + 1):
            for k in range(0, M // N[2] + 1):
                for a in range(0, M // N[3] + 1):
                    for b in range(0, M // N[4] + 1):
                        sum_res = N[0] * i + N[1] * j + N[2] * k + N[3] * a + N[4] * b
                        delta = M - sum_res
                        if delta < 0:
                            break  
                        if  0 <= delta < N[0]:
                            count += 1
 
elif length == 6:
    for i in range(0, M // N[0] + 1):
        for j in range(0, M // N[1] + 1):
            for k in range(0, M // N[2] + 1):
                for a in range(0, M // N[3] + 1):
                    for b in range(0, M // N[4] + 1):
                        for c in range(0, M // N[5] + 1):
                            sum_res = N[0] * i + N[1] * j + N[2] * k + N[3] * a + N[4] * b + N[5] * c
                            delta = M - sum_res
                            if delta < 0:
                                break  
                            if  0 <= delta < N[0]:
                                count += 1                         
print(count)
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
 
set<vector<int>> res;
 
void dfs(vector<int>const& nums, int start_index, int target, int max_ext_val, vector<int> path) {
    if (target < 0)
      return ;
    
    if (target == 0 || target < max_ext_val) {
        
        res.insert(path);
        return ;
    }
    
 
    for (int i = start_index; i < nums.size(); ++i) {
        path.push_back(nums[i]);
        dfs(nums, i, target - nums[i],  max_ext_val, path);
        path.pop_back();        
    }
}
 
 
int main() {
    
    int value;
    vector<int> N;
    while (cin >> value) {
        N.push_back(value);
    }
 
    int M = N.back();
    N.pop_back();
 
    int min_value = *min_element(N.begin(), N.end());
 
    dfs(N, 0, M,  min_value, {});
    
    cout << res.size();
    
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值