• LeetCode 363 期周赛


    在这里插入图片描述

    2859.计算 K 置位下标对应元素的和

    题目

    给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。

    请你用整数形式返回 nums 中的特定元素之 和 ,这些特定元素满足:其对应下标的二进制表示中恰存在 k 个置位。

    整数的二进制表示中的 1 就是这个整数的 置位 。

    例如,21 的二进制表示为 10101 ,其中有 3 个置位。

    示例 1:

    输入:nums = [5,10,1,5,2], k = 1
    输出:13
    解释:下标的二进制表示是:
    0 = 0002
    1 = 0012
    2 = 0102
    3 = 0112
    4 = 1002 下标 1、2 和 4 在其二进制表示中都存在 k = 1 个置位。
    因此,答案为 nums[1] + nums[2] + nums[4] = 13 。

    示例 2:

    输入:nums = [4,3,2,1], k = 2
    输出:1
    解释:下标的二进制表示是:
    0 = 002
    1 = 012
    2 = 102
    3 = 112
    只有下标 3 的二进制表示中存在 k = 2 个置位。
    因此,答案为 nums[3] = 1 。

    思路

    判断每个nums的下标有几个二进制1,如果个数等于k,那么加到sum中即可。

    class Solution {
    public:
       int countOnes(int num) {
           int count = 0;
           while (num != 0) {
               count += num & 1;
               num >>= 1;
           }   
           return count;
       }
       
       int sumIndicesWithKSetBits(vector<int>& nums, int k) {
           int len=nums.size();
           long long int sum=0;
           for(int i=0;i<len;++i){
               if(countOnes(i)==k){
                   sum+=nums[i];
               }
           }
           return sum;
       }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    2860.让所有学生保持开心的分组方法数

    题目

    给你一个下标从 0 开始、长度为 n 的整数数组 nums ,其中 n 是班级中学生的总数。班主任希望能够在让所有学生保持开心的情况下选出一组学生:
    如果能够满足下述两个条件之一,则认为第 i 位学生将会保持开心:
    这位学生被选中,并且被选中的学生人数 严格大于 nums[i] 。
    这位学生没有被选中,并且被选中的学生人数 严格小于 nums[i] 。
    返回能够满足让所有学生保持开心的分组方法的数目。

    示例 1:

    输入:nums = [1,1]
    输出:2 解释:
    有两种可行的方法:
    班主任没有选中学生。
    班主任选中所有学生形成一组。
    如果班主任仅选中一个学生来完成分组,那么两个学生都无法保持开心。
    因此,仅存在两种可行的方法。

    示例 2:

    输入:nums = [6,0,3,3,6,7,2,7]
    输出:3
    解释: 存在三种可行的方法:
    班主任选中下标为 1 的学生形成一组。
    班主任选中下标为 1、2、3、6 的学生形成一组。
    班主任选中所有学生形成一组。

    思路

    首先,先按照升序进行排列。随后建立一个bool的数组,如果nums数组中包含的数,那么一定不可能是ans,跳过。

    代码

    class Solution {
    public:
        int countWays(vector<int>& nums) {
            int len=nums.size();
            //升序排列
            sort(nums.begin(),nums.end());
            vector<bool> flage(len+5,true);
            
            //nums数组在包含的,不可能是要选的人数
            for(int i=0;i<len;++i){
                if(flage[nums[i]]){
                    flage[nums[i]]=false;
                }
            }
            
            //遍历选0人和全选的情况
            int count=0,res=0;
            for(int i=0;i<=len;++i){
                if(!flage[i])
                    continue;
                count=0;
                //遍历数组的每一个值
               auto it=upper_bound(nums.begin(), nums.end(), i);
               count=distance(nums.begin(), it);
                if(count==i)
                    res++;
            }
            return res;
        }
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    2861.最大合金数

    题目
    假设你是一家合金制造公司的老板,你的公司使用多种金属来制造合金。现在共有 n 种不同类型的金属可以使用,并且你可以使用 k 台机器来制造合金。每台机器都需要特定数量的每种金属来创建合金。

    对于第 i 台机器而言,创建合金需要 composition[i][j] 份 j 类型金属。最初,你拥有 stock[i] 份 i 类型金属,而每购入一份 i 类型金属需要花费 cost[i] 的金钱。

    给你整数 n、k、budget,下标从 1 开始的二维数组 composition,两个下标从 1 开始的数组 stock 和 cost,请你在预算不超过 budget 金钱的前提下,最大化 公司制造合金的数量。

    所有合金都需要由同一台机器制造。

    返回公司可以制造的最大合金数。

    示例 1:

    输入:n = 3, k = 2, budget = 15, composition = [[1,1,1],[1,1,10]], stock = [0,0,0], cost = [1,2,3]
    输出:2
    解释:最优的方法是使用第 1 台机器来制造合金。
    要想制造 2 份合金,我们需要购买:

    • 2 份第 1 类金属。
    • 2 份第 2 类金属。
    • 2 份第 3 类金属。
      总共需要 2 * 1 + 2 * 2 + 2 * 3 = 12 的金钱,小于等于预算 15 。
      注意,我们最开始时候没有任何一类金属,所以必须买齐所有需要的金属。
      可以证明在示例条件下最多可以制造 2 份合金。

    示例 2:

    输入:n = 3, k = 2, budget = 15, composition = [[1,1,1],[1,1,10]], stock = [0,0,100], cost = [1,2,3]
    输出:5
    解释:最优的方法是使用第 2 台机器来制造合金。
    要想制造 5 份合金,我们需要购买:

    • 5 份第 1 类金属。
    • 5 份第 2 类金属。
    • 0 份第 3 类金属。
      总共需要 5 * 1 + 5 * 2 + 0 * 3 = 15 的金钱,小于等于预算 15 。
      可以证明在示例条件下最多可以制造 5 份合金。
      示例 3:

    输入:n = 2, k = 3, budget = 10, composition = [[2,1],[1,2],[1,1]], stock = [1,1], cost = [5,5]
    输出:2
    解释:最优的方法是使用第 3 台机器来制造合金。
    要想制造 2 份合金,我们需要购买:

    • 1 份第 1 类金属。
    • 1 份第 2 类金属。
      总共需要 1 * 5 + 1 * 5 = 10 的金钱,小于等于预算 10 。
      可以证明在示例条件下最多可以制造 2 份合金。

    思路

    假设要制造 num份合金,由于num越小花费的钱越少num 越多,花费的钱越多,有单调性,可以二分。

    代码

    class Solution {
    public:
        int maxNumberOfAlloys(int n, int k, int budget, vector<vector<int>> &composition, vector<int> &stock, vector<int> &cost) {
            int ans = 0;
            int mx = *min_element(stock.begin(), stock.end()) + budget;
            for (auto &com: composition) {
                auto check = [&](long long num) -> bool {
                    long long money = 0;
                    for (int i = 0; i < n; i++) {
                        if (stock[i] < com[i] * num) {
                            money += (com[i] * num - stock[i]) * cost[i];
                            if (money > budget) {
                                return false;
                            }
                        }
                    }
                    return true;
                };
                int left = 0, right = mx + 1;
                while (left + 1 < right) { // 开区间写法
                    int mid = (left + right) / 2;
                    (check(mid) ? left : right) = mid;
                }
                ans = max(ans, left);
            }
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    2862.完全子集的最大元素和

    题目

    给你一个下标从 1 开始、由 n 个整数组成的数组。

    如果一组数字中每对元素的乘积都是一个完全平方数,则称这组数字是一个 完全集 。

    下标集 {1, 2, …, n} 的子集可以表示为 {i1, i2, …, ik},我们定义对应该子集的 元素和 为 nums[i1] + nums[i2] + … + nums[ik] 。

    返回下标集 {1, 2, …, n} 的 完全子集 所能取到的 最大元素和 。

    完全平方数是指可以表示为一个整数和其自身相乘的数。

    示例 1:

    输入:nums = [8,7,3,5,7,2,4,9]
    输出:16
    解释:除了由单个下标组成的子集之外,还有两个下标集的完全子集:{1,4} 和 {2,8} 。
    与下标 1 和 4 对应的元素和等于 nums[1] + nums[4] = 8 + 5 = 13 。
    与下标 2 和 8 对应的元素和等于 nums[2] + nums[8] = 7 + 9 = 16 。
    因此,下标集的完全子集可以取到的最大元素和为 16 。

    示例 2:

    输入:nums = [5,10,3,10,1,13,7,9,4]
    输出:19
    解释:除了由单个下标组成的子集之外,还有四个下标集的完全子集:{1,4}、{1,9}、{2,8}、{4,9} 和 {1,4,9} 。
    与下标 1 和 4 对应的元素和等于 nums[1] + nums[4] = 5 + 10 = 15 。
    与下标 1 和 9 对应的元素和等于 nums[1] + nums[9] = 5 + 4 = 9 。
    与下标 2 和 8 对应的元素和等于 nums[2] + nums[8] = 10 + 9 = 19 。
    与下标 4 和 9 对应的元素和等于 nums[4] + nums[9] = 10 + 4 = 14 。
    与下标 1、4 和 9 对应的元素和等于 nums[1] + nums[4] + nums[9] = 5 + 10 + 4 = 19 。
    因此,下标集的完全子集可以取到的最大元素和为 19 。

    思路

    根据题意,如果同一组中有两个数,它们的下标的 core\text{core}core 值不同,那么这两个数相乘,就不是一个完全平方数。
    所以,同一组内的数字下标的 core\text{core}core 值必须都一样。 那么按照下标的 core\text{core}core
    值分组,累加同一组的元素和,最大元素和即为答案。

    代码

    class Solution {
        int core(int n) {
            int res = 1;
            for (int i = 2; i * i <= n; i++) {
                int e = 0;
                while (n % i == 0) {
                    e ^= 1;
                    n /= i;
                }
                if (e) {
                    res *= i;
                }
            }
            if (n > 1) {
                res *= n;
            }
            return res;
        }
    
    public:
        long long maximumSum(vector<int> &nums) {
            vector<long long> sum(nums.size() + 1);
            for (int i = 0; i < nums.size(); i++) {
                sum[core(i + 1)] += nums[i];
            }
            return *max_element(sum.begin(), sum.end());
        }
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
  • 相关阅读:
    JAVA应用中线程池设置多少合适?
    C++多态
    fastify-swagger 7.4.1
    使用python生成文字图片,画圆圈 ,生成圆形图片
    vue computed和watch的区别 v-if和v-show的区别 v-if和v-for优先级的问题
    SpringBoot发送请求与匹配响应信息
    2.Modbus通信协议-软件调试4个工具软件(推荐)
    系统表空间-mysql详解(四)
    Flink 窗口处理函数 WindowFunction
    【英语:基础高阶_经典外刊阅读】L3.长句子扒皮—如何快速寻找主干
  • 原文地址:https://blog.csdn.net/m0_73731708/article/details/133000542