当前位置:首页 > 编程笔记 > 正文
已解决

周赛363(模拟、排序+枚举、二分答案、思维题)

来自网友在路上 173873提问 提问时间:2023-09-25 03:00:38阅读次数: 73

最佳答案 问答题库738位专家为你答疑解惑

文章目录

  • 周赛363
    • [2859. 计算 K 置位下标对应元素的和](https://leetcode.cn/problems/sum-of-values-at-indices-with-k-set-bits/)
      • 模拟
    • [2860. 让所有学生保持开心的分组方法数](https://leetcode.cn/problems/happy-students/)
      • 排序 + 枚举
    • [2861. 最大合金数](https://leetcode.cn/problems/maximum-number-of-alloys/)
      • 二分答案
    • [2862. 完全子集的最大元素和](https://leetcode.cn/problems/maximum-element-sum-of-a-complete-subset-of-indices/)
      • 数学

周赛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 。

提示:

  • 1 <= nums.length <= 1000
  • 1 <= nums[i] <= 105
  • 0 <= k <= 10

模拟

class Solution {public int sumIndicesWithKSetBits(List<Integer> nums, int k) {int cnt = 0;for(int i = 0; i < nums.size(); i++){if(Integer.bitCount(i) == k)cnt += nums.get(i);}return cnt;}
}

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 的学生形成一组。
班主任选中所有学生形成一组。 

提示:

  • 1 <= nums.length <= 105
  • 0 <= nums[i] < nums.length

排序 + 枚举

https://leetcode.cn/problems/happy-students/solutions/2446022/pai-xu-pythonjavacgojs-by-endlesscheng-ptzl/

class Solution {public int countWays(List<Integer> nums) {int[] a = nums.stream().mapToInt(i -> i).toArray();Arrays.sort(a);int n = a.length;int ans = a[0] > 0 ? 1 : 0; // 一个学生都不选的情况for(int i = 0; i < n-1; i++){if(a[i] < i+1 && i+1 < a[i+1])ans++;}return ans + 1; // +1 是因为可以都选}
}

2861. 最大合金数

中等

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

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

给你整数 nkbudget,下标从 1 开始的二维数组 composition,两个下标从 1 开始的数组 stockcost,请你在预算不超过 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 份合金。

提示:

  • 1 <= n, k <= 100
  • 0 <= budget <= 108
  • composition.length == k
  • composition[i].length == n
  • 1 <= composition[i][j] <= 100
  • stock.length == cost.length == n
  • 0 <= stock[i] <= 108
  • 1 <= cost[i] <= 100

二分答案

https://leetcode.cn/problems/maximum-number-of-alloys/solutions/2446024/er-fen-da-an-fu-ti-dan-by-endlesscheng-3jdr/

class Solution {// 挨个判断每台机器最多可以制造多少份合金。public int maxNumberOfAlloys(int n, int k, int budget, List<List<Integer>> composition, List<Integer> Stock, List<Integer> Cost) {int ans = 0;int mx = Collections.min(Stock) + budget;int[] stock = Stock.stream().mapToInt(i -> i).toArray();int[] cost = Cost.stream().mapToInt(i -> i).toArray();for(List<Integer> Com : composition){int[] com = Com.stream().mapToInt(i -> i).toArray();int left = 0, right = mx + 1;while(left < right){int mid = (left + right + 1) >> 1;boolean ok = true;long money = 0;// 计算一下用 i 机器能否达到要求for(int i = 0; i < n; i++){if(stock[i] < (long) com[i] * mid){money += ((long) com[i] * mid - stock[i]) * cost[i];if(money > budget){ok = false;break;}}}if(!ok){right = mid - 1;}else{left = mid;}}ans = Math.max(ans, right);}return ans;}
}

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 。

提示:

  • 1 <= n == nums.length <= 104
  • 1 <= nums[i] <= 109

数学

class Solution {/**定义 core(n) 为 n 去处完全平方因子后的剩余结果若同一组有两个数,它们的下标的core值不同,那么这两个数相乘,就不是一个完全平方数所以 同一组的数字下标的core值必须都一样按照下标的core值分组,累加同一组的元素和,最大元素和即为答案*/public long maximumSum(List<Integer> nums) {long ans = 0;int n = nums.size();long[] sum = new long[n+1];for(int i = 0; i < nums.size(); i++){int c = core(i + 1);sum[c] += nums.get(i);ans = Math.max(ans, sum[c]);}return ans;}// 质因数分解,core(n) 为 n 去处完全平方因子后的剩余结果private 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 == 1) {res *= i;}}if (n > 1) {res *= n;}return res;}
}
查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"周赛363(模拟、排序+枚举、二分答案、思维题)":http://eshow365.cn/6-13176-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!