Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3e9c1dc

Browse files
committed
第460场周赛T1~T4 (4)
1 parent 5779906 commit 3e9c1dc

File tree

8 files changed

+384
-0
lines changed

8 files changed

+384
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import java.util.Arrays;
2+
3+
public class Solution3627 {
4+
public long maximumMedianSum(int[] nums) {
5+
int n = nums.length;
6+
Arrays.sort(nums);
7+
long ans = 0;
8+
// bob 拿数量最少的三分之一
9+
for (int i = n / 3; i < n; i += 2) {
10+
ans += nums[i];
11+
}
12+
return ans;
13+
}
14+
}
15+
/*
16+
3627. 中位数之和的最大值
17+
https://leetcode.cn/problems/maximum-median-sum-of-subsequences-of-size-3/description/
18+
19+
第 460 场周赛 T1。
20+
21+
给你一个整数数组 nums,其长度可以被 3 整除。
22+
你需要通过多次操作将数组清空。在每一步操作中,你可以从数组中选择任意三个元素,计算它们的 中位数 ,并将这三个元素从数组中移除。
23+
奇数长度数组的 中位数 定义为数组按非递减顺序排序后位于中间的元素。
24+
返回通过所有操作得到的 中位数之和的最大值 。
25+
提示:
26+
1 <= nums.length <= 5 * 10^5
27+
nums.length % 3 == 0
28+
1 <= nums[i] <= 10^9
29+
30+
贪心。
31+
时间复杂度 O(nlogn)。
32+
相似题目: 1561. 你可以获得的最大硬币数目
33+
https://leetcode.cn/problems/maximum-number-of-coins-you-can-get/description/
34+
*/
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
public class Solution3628 {
2+
public long numOfSubsequences(String s) {
3+
long ans = numDistinct(s, "LCT"); // 不操作
4+
long extra = numDistinct(s, "CT"); // 最前面加 L
5+
extra = Math.max(extra, numDistinct(s, "LC")); // 最后面加 T
6+
extra = Math.max(extra, calcInsertC(s.toCharArray())); // 中间加 C
7+
return ans + extra;
8+
}
9+
10+
// 计算插入 C 额外产生的 LCT 子序列个数的最大值
11+
private long calcInsertC(char[] s) {
12+
int cntT = 0;
13+
for (char c : s) {
14+
if (c == 'T') {
15+
cntT++;
16+
}
17+
}
18+
19+
long res = 0;
20+
int cntL = 0;
21+
for (char c : s) {
22+
if (c == 'T') {
23+
cntT--;
24+
}
25+
if (c == 'L') {
26+
cntL++;
27+
}
28+
res = Math.max(res, (long) cntL * cntT);
29+
}
30+
return res;
31+
}
32+
33+
// 115
34+
private long numDistinct(String s, String t) {
35+
int n = s.length();
36+
int m = t.length();
37+
long[][] f = new long[n + 1][m + 1];
38+
f[0][0] = 1;
39+
for (int i = 0; i < n; i++) {
40+
f[i + 1][0] = 1;
41+
for (int j = 0; j <= i && j < m; j++) {
42+
if (s.charAt(i) == t.charAt(j)) {
43+
f[i + 1][j + 1] = (f[i][j] + f[i][j + 1]);
44+
} else {
45+
f[i + 1][j + 1] = f[i][j + 1];
46+
}
47+
}
48+
}
49+
return f[n][m];
50+
}
51+
}
52+
/*
53+
3628. 插入一个字母的最大子序列数
54+
https://leetcode.cn/problems/maximum-number-of-subsequences-after-one-inserting/description/
55+
56+
第 460 场周赛 T2。
57+
58+
给你一个由大写英文字母组成的字符串 s。
59+
你可以在字符串的 任意 位置(包括字符串的开头或结尾)最多插入一个 大写英文字母。
60+
返回在 最多插入一个字母 后,字符串中可以形成的 "LCT" 子序列的 最大 数量。
61+
子序列 是从另一个字符串中删除某些字符(可以不删除)且不改变剩余字符顺序后得到的一个 非空 字符串。
62+
提示:
63+
1 <= s.length <= 10^5
64+
s 仅由大写英文字母组成。
65+
66+
不插入情况 + extra(最前面加 L, 最后面加 T, 中间加 C)三种情况
67+
时间复杂度 O(n)。
68+
*/
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import java.util.ArrayList;
2+
import java.util.Arrays;
3+
import java.util.HashMap;
4+
import java.util.List;
5+
import java.util.Map;
6+
7+
public class Solution3629 {
8+
private static final int MX = (int) (1e6 + 1);
9+
private static final List<Integer>[] primeFactors = new ArrayList[MX];
10+
11+
static {
12+
Arrays.setAll(primeFactors, e -> new ArrayList<>());
13+
// 预处理每个数的质因子列表,思路同埃氏筛
14+
for (int i = 2; i < MX; i++) {
15+
if (primeFactors[i].isEmpty()) { // i 是质数
16+
for (int j = i; j < MX; j += i) { // i 的倍数有质因子 i
17+
primeFactors[j].add(i);
18+
}
19+
}
20+
}
21+
}
22+
23+
public int minJumps(int[] nums) {
24+
int n = nums.length;
25+
Map<Integer, List<Integer>> groups = new HashMap<>();
26+
for (int i = 0; i < n; i++) {
27+
for (int p : primeFactors[nums[i]]) {
28+
// 对于质数 p,可以跳到下标 i
29+
groups.computeIfAbsent(p, e -> new ArrayList<>()).add(i);
30+
}
31+
}
32+
33+
int ans = 0;
34+
boolean[] vis = new boolean[n];
35+
vis[0] = true;
36+
List<Integer> q = List.of(0);
37+
38+
while (true) {
39+
List<Integer> tmp = q;
40+
q = new ArrayList<>();
41+
for (int i : tmp) {
42+
if (i == n - 1) {
43+
return ans;
44+
}
45+
List<Integer> idx = groups.computeIfAbsent(nums[i], e -> new ArrayList<>());
46+
idx.add(i + 1);
47+
if (i > 0) {
48+
idx.add(i - 1);
49+
}
50+
for (int j : idx) { // 可以从 i 跳到 j
51+
if (!vis[j]) {
52+
vis[j] = true;
53+
q.add(j);
54+
}
55+
}
56+
idx.clear(); // 避免重复访问下标列表
57+
}
58+
ans++;
59+
}
60+
}
61+
}
62+
/*
63+
3629. 通过质数传送到达终点的最少跳跃次数
64+
https://leetcode.cn/problems/minimum-jumps-to-reach-end-via-prime-teleportation/description/
65+
66+
第 460 场周赛 T3。
67+
68+
给你一个长度为 n 的整数数组 nums。
69+
你从下标 0 开始,目标是到达下标 n - 1。
70+
在任何下标 i 处,你可以执行以下操作之一:
71+
- 移动到相邻格子:跳到下标 i + 1 或 i - 1,如果该下标在边界内。
72+
- 质数传送:如果 nums[i] 是一个质数 p,你可以立即跳到任何满足 nums[j] % p == 0 的下标 j 处,且下标 j != i 。
73+
返回到达下标 n - 1 所需的 最少 跳跃次数。
74+
质数 是一个大于 1 的自然数,只有两个因子,1 和它本身。
75+
提示:
76+
1 <= n == nums.length <= 10^5
77+
1 <= nums[i] <= 10^6
78+
79+
两种方法:正向 BFS / 逆向 BFS
80+
https://leetcode.cn/problems/minimum-jumps-to-reach-end-via-prime-teleportation/solutions/3734792/bfspythonjavacgo-by-endlesscheng-bu60/
81+
时间复杂度 O(nlogU)。其中 n 是 nums 的长度 U=max(nums)
82+
rating 2148 (clist.by)
83+
*/
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import java.util.Arrays;
2+
3+
public class Solution3630 {
4+
public long maximizeXorAndXor(int[] nums) {
5+
int n = nums.length;
6+
int maxVal = Arrays.stream(nums).max().orElseThrow();
7+
int sz = 32 - Integer.numberOfLeadingZeros(maxVal);
8+
9+
// 预处理所有子集的 AND 和 XOR(刷表法)
10+
int u = 1 << n;
11+
int[] subAnd = new int[u];
12+
int[] subXor = new int[u];
13+
subAnd[0] = -1;
14+
for (int i = 0; i < n; i++) {
15+
int x = nums[i];
16+
int highBit = 1 << i;
17+
for (int mask = 0; mask < highBit; mask++) {
18+
subAnd[highBit | mask] = subAnd[mask] & x;
19+
subXor[highBit | mask] = subXor[mask] ^ x;
20+
}
21+
}
22+
subAnd[0] = 0;
23+
24+
long ans = 0;
25+
for (int i = 0; i < u; i++) {
26+
int j = (u - 1) ^ i;
27+
ans = Math.max(ans, subAnd[i] + maxXor2(j, subXor[j], nums, sz));
28+
}
29+
return ans;
30+
}
31+
32+
private long maxXor2(int sub, int xor, int[] nums, int sz) {
33+
XorBasis b = new XorBasis(sz);
34+
for (int i = 0; i < nums.length; i++) {
35+
if ((sub >> i & 1) > 0) {
36+
// 只考虑有偶数个 1 的比特位(xor 在这些比特位上是 0)
37+
b.insert(nums[i] & ~xor);
38+
}
39+
}
40+
return xor + b.maxXor() * 2L;
41+
}
42+
43+
44+
// 线性基模板
45+
static class XorBasis {
46+
private final int[] b;
47+
48+
public XorBasis(int n) {
49+
b = new int[n];
50+
}
51+
52+
public void insert(int x) {
53+
while (x > 0) {
54+
int i = 31 - Integer.numberOfLeadingZeros(x); // x 的最高位
55+
if (b[i] == 0) { // x 和之前的基是线性无关的
56+
b[i] = x; // 新增一个基,最高位为 i
57+
return;
58+
}
59+
x ^= b[i]; // 保证参与 maxXor 的基的最高位是互不相同的,方便我们贪心
60+
}
61+
// 正常循环结束,此时 x=0,说明一开始的 x 可以被已有基表出,不是一个线性无关基
62+
}
63+
64+
public int maxXor() {
65+
int res = 0;
66+
// 从高到低贪心:越高的位,越必须是 1
67+
// 由于每个位的基至多一个,所以每个位只需考虑异或一个基,若能变大,则异或之
68+
for (int i = b.length - 1; i >= 0; i--) {
69+
res = Math.max(res, res ^ b[i]);
70+
}
71+
return res;
72+
}
73+
}
74+
}
75+
/*
76+
3630. 划分数组得到最大异或运算和与运算之和
77+
https://leetcode.cn/problems/partition-array-for-maximum-xor-and-and/description/
78+
79+
第 460 场周赛 T4。
80+
81+
给你一个整数数组 nums。
82+
将数组划分为 三 个(可以为空)子序列 A、B 和 C,使得 nums 中的每个元素 恰好 属于一个子序列。
83+
你的目标是 最大化 以下值:XOR(A) + AND(B) + XOR(C)
84+
其中:
85+
- XOR(arr) 表示 arr 中所有元素的按位异或结果。如果 arr 为空,结果定义为 0。
86+
- AND(arr) 表示 arr 中所有元素的按位与结果。如果 arr 为空,结果定义为 0。
87+
返回可实现的最 大 值。
88+
注意: 如果有多种划分方式得到相同的 最大 和,你可以按其中任何一种划分。
89+
子序列 是指一个数组通过删除一些或不删除任何元素,不改变剩余元素的顺序得到的元素序列。
90+
提示:
91+
1 <= nums.length <= 19
92+
1 <= nums[i] <= 10^9
93+
94+
线性基(线性异或基)
95+
式子变形 + 线性基 + 最优性剪枝 https://leetcode.cn/problems/partition-array-for-maximum-xor-and-and/submissions/649144010/
96+
如果直接三进制枚举,时间复杂度是 O(3^n) = 3^19 = 1,162,261,467 = 1e9
97+
rating 2747 (clist.by)
98+
*/
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution3627Tests {
5+
private final Solution3627 solution3627 = new Solution3627();
6+
7+
@Test
8+
public void example1() {
9+
int[] nums = {2, 1, 3, 2, 1, 3};
10+
long expected = 5;
11+
Assertions.assertEquals(expected, solution3627.maximumMedianSum(nums));
12+
}
13+
14+
@Test
15+
public void example2() {
16+
int[] nums = {1, 1, 10, 10, 10, 10};
17+
long expected = 20;
18+
Assertions.assertEquals(expected, solution3627.maximumMedianSum(nums));
19+
}
20+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution3628Tests {
5+
private final Solution3628 solution3628 = new Solution3628();
6+
7+
@Test
8+
public void example1() {
9+
String s = "LMCT";
10+
long expected = 2;
11+
Assertions.assertEquals(expected, solution3628.numOfSubsequences(s));
12+
}
13+
14+
@Test
15+
public void example2() {
16+
String s = "LCCT";
17+
long expected = 4;
18+
Assertions.assertEquals(expected, solution3628.numOfSubsequences(s));
19+
}
20+
21+
@Test
22+
public void example3() {
23+
String s = "L";
24+
long expected = 0;
25+
Assertions.assertEquals(expected, solution3628.numOfSubsequences(s));
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution3629Tests {
5+
private final Solution3629 solution3629 = new Solution3629();
6+
7+
@Test
8+
public void example1() {
9+
int[] nums = {1, 2, 4, 6};
10+
int expected = 2;
11+
Assertions.assertEquals(expected, solution3629.minJumps(nums));
12+
}
13+
14+
@Test
15+
public void example2() {
16+
int[] nums = {2, 3, 4, 7, 9};
17+
int expected = 2;
18+
Assertions.assertEquals(expected, solution3629.minJumps(nums));
19+
}
20+
21+
@Test
22+
public void example3() {
23+
int[] nums = {4, 6, 5, 8};
24+
int expected = 3;
25+
Assertions.assertEquals(expected, solution3629.minJumps(nums));
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution3630Tests {
5+
private final Solution3630 solution3630 = new Solution3630();
6+
7+
@Test
8+
public void example1() {
9+
int[] nums = {2, 3};
10+
long expected = 5;
11+
Assertions.assertEquals(expected, solution3630.maximizeXorAndXor(nums));
12+
}
13+
14+
@Test
15+
public void example2() {
16+
int[] nums = {1, 3, 2};
17+
long expected = 6;
18+
Assertions.assertEquals(expected, solution3630.maximizeXorAndXor(nums));
19+
}
20+
21+
@Test
22+
public void example3() {
23+
int[] nums = {2, 3, 6, 7};
24+
long expected = 15;
25+
Assertions.assertEquals(expected, solution3630.maximizeXorAndXor(nums));
26+
}
27+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /