第 363 场力扣周赛

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

模拟。

1
2
3
4
5
6
7
8
9
10
11
class Solution {
public int sumIndicesWithKSetBits(List<Integer> nums, int k) {
int n = nums.size(), ans = 0;
for (int i = 0; i < n; i++) {
if (Integer.bitCount(i) == k) {
ans += nums.get(i);
}
}
return ans;
}
}

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

比赛时又写复杂了,当时是想到所有相同的数都必须同时选,所以加了一层循环来跳过相同的数。但是相同的数天然的不满足判断条件,所以不需要这样写。这题唯一需要注意的就是特判全都不选的情况,以及全都选的情况必定满足,可以直接加到答案里(以减少判断代码)。

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public int countWays(List<Integer> nums) {
Collections.sort(nums);
int n = nums.size(), ans = 1;
if (nums.get(0) > 0) ans++;
for (int i = 0; i < n - 1; i++) {
if (i + 1 > nums.get(i) && i + 1 < nums.get(i + 1)) {
ans++;
}
}
return ans;
}
}

最大合金数

比赛时又又写复杂了,当时是把所有的库存都清除了再二分的,其实可以直接二分!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public int maxNumberOfAlloys(int n, int k, int budget, List<List<Integer>> composition, List<Integer> stock, List<Integer> cost) {
int ans = 0;
for (var cur : composition) {
int lo = 0, hi = (int) 2e8;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
long cnt = 0L;
for (int i = 0; i < n; i++) {
cnt += Math.max((long) cur.get(i) * mid - stock.get(i), 0L) * cost.get(i);
}
if (cnt <= budget) lo = mid + 1;
else hi = mid - 1;
}
ans = Math.max(ans, hi);
}
return ans;
}
}

完全子集的最大元素和

注意题目的描述是每对元素的乘积都是完全平方数。朴素的想法就是对下标进行质因数分解,将所有出现次数为奇数质因数相乘,其结果作为桶的下标,把所有同类的数放在同一个桶里面,然后对每个桶求和取最大值,这样的时间复杂度是 \(O(n\sqrt{n})\)。但是有 \(O(n)\) 的解法,如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public long maximumSum(List<Integer> nums) {
long ans = 0L;
int n = nums.size();
for (int i = 1; i <= n; i++) {
long sum = 0L;
for (int j = 1; i * j * j <= n; j++) {
sum += nums.get(i * j * j - 1);
}
ans = Math.max(ans, sum);
}
return ans;
}
}
作者

Ligh0x74

发布于

2023-09-17

更新于

2023-09-17

许可协议

评论