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 b9af3de

Browse files
committed
第458场周赛T1~T4 (4)
1 parent 82efcfa commit b9af3de

File tree

8 files changed

+376
-0
lines changed

8 files changed

+376
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
public class Solution3612 {
2+
public String processStr(String s) {
3+
StringBuilder ans = new StringBuilder();
4+
for (char c : s.toCharArray()) {
5+
if (c == '*') {
6+
if (!ans.isEmpty()) ans.deleteCharAt(ans.length() - 1);
7+
} else if (c == '#') {
8+
ans.append(ans);
9+
} else if (c == '%') {
10+
ans.reverse();
11+
} else {
12+
ans.append(c);
13+
}
14+
}
15+
return ans.toString();
16+
}
17+
}
18+
/*
19+
3612. 用特殊操作处理字符串 I
20+
https://leetcode.cn/problems/process-string-with-special-operations-i/description/
21+
22+
第 458 场周赛 T1。
23+
24+
给你一个字符串 s,它由小写英文字母和特殊字符:*、# 和 % 组成。
25+
请根据以下规则从左到右处理 s 中的字符,构造一个新的字符串 result:
26+
- 如果字符是 小写 英文字母,则将其添加到 result 中。
27+
- 字符 '*' 会 删除 result 中的最后一个字符(如果存在)。
28+
- 字符 '#' 会 复制 当前的 result 并 追加 到其自身后面。
29+
- 字符 '%' 会 反转 当前的 result。
30+
在处理完 s 中的所有字符后,返回最终的字符串 result。
31+
提示:
32+
1 <= s.length <= 20
33+
s 只包含小写英文字母和特殊字符 *、# 和 %。
34+
35+
中国时间 2025年07月13日 周日 10:30
36+
佛山。
37+
模拟。
38+
*/
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import java.util.Arrays;
2+
import java.util.Comparator;
3+
4+
public class Solution3613 {
5+
public int minCost(int n, int[][] edges, int k) {
6+
if (n == k) return 0;
7+
DSU dsu = new DSU(n);
8+
Arrays.sort(edges, Comparator.comparingInt(o -> o[2]));
9+
for (int[] e : edges) {
10+
dsu.union(e[0], e[1]);
11+
if (dsu.sz == k) return e[2];
12+
}
13+
return edges[edges.length - 1][2];
14+
}
15+
16+
static class DSU {
17+
int[] fa;
18+
int sz;
19+
20+
public DSU(int n) {
21+
fa = new int[n];
22+
for (int i = 0; i < n; i++) fa[i] = i;
23+
sz = n;
24+
}
25+
26+
int find(int x) { // 查找
27+
return x == fa[x] ? fa[x] : (fa[x] = find(fa[x]));
28+
}
29+
30+
void union(int p, int q) { // 合并
31+
p = find(p);
32+
q = find(q);
33+
if (p == q) return;
34+
fa[q] = p;
35+
sz--;
36+
}
37+
}
38+
}
39+
/*
40+
3613. 最小化连通分量的最大成本
41+
https://leetcode.cn/problems/minimize-maximum-component-cost/description/
42+
43+
第 458 场周赛 T2。
44+
45+
给你一个无向连通图,包含 n 个节点,节点编号从 0 到 n - 1,以及一个二维整数数组 edges,其中 edges[i] = [ui, vi, wi] 表示一条连接节点 ui 和节点 vi 的无向边,边权为 wi,另有一个整数 k。
46+
你可以从图中移除任意数量的边,使得最终的图中 最多 只包含 k 个连通分量。
47+
连通分量的 成本 定义为该分量中边权的 最大值 。如果一个连通分量没有边,则其代价为 0。
48+
请返回在移除这些边之后,在所有连通分量之中的 最大成本 的 最小可能值 。
49+
提示:
50+
1 <= n <= 5 * 10^4
51+
0 <= edges.length <= 10^5
52+
edges[i].length == 3
53+
0 <= ui, vi < n
54+
1 <= wi <= 10^6
55+
1 <= k <= n
56+
输入图是连通图。
57+
58+
并查集。从小到大合并。
59+
相似题目: 3608. 包含 K 个连通分量需要的最小时间
60+
https://leetcode.cn/problems/minimum-time-for-k-connected-components/description/
61+
*/
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
public class Solution3614 {
2+
public char processStr(String S, long k) {
3+
char[] s = S.toCharArray();
4+
int n = s.length;
5+
long[] size = new long[n];
6+
long sz = 0;
7+
for (int i = 0; i < n; i++) {
8+
char c = s[i];
9+
if (c == '*') {
10+
sz = Math.max(sz - 1, 0);
11+
} else if (c == '#') {
12+
sz *= 2; // 题目保证 sz <= 1e15
13+
} else if (c != '%') { // c 是字母
14+
sz++;
15+
}
16+
size[i] = sz;
17+
}
18+
19+
if (k >= size[n - 1]) { // 下标越界
20+
return '.';
21+
}
22+
23+
// 迭代
24+
for (int i = n - 1; ; i--) {
25+
char c = s[i];
26+
sz = size[i];
27+
if (c == '#') {
28+
if (k >= sz / 2) { // k 在复制后的右半边
29+
k -= sz / 2;
30+
}
31+
} else if (c == '%') {
32+
k = sz - 1 - k; // 反转前的下标为 sz-1-k 的字母就是答案
33+
} else if (c != '*' && k == sz - 1) { // 找到答案
34+
return c;
35+
}
36+
}
37+
}
38+
}
39+
/*
40+
3614. 用特殊操作处理字符串 II
41+
https://leetcode.cn/problems/process-string-with-special-operations-ii/description/
42+
43+
第 458 场周赛 T3。
44+
45+
给你一个字符串 s,由小写英文字母和特殊字符:'*'、'#' 和 '%' 组成。
46+
同时给你一个整数 k。
47+
请根据以下规则从左到右处理 s 中每个字符,构造一个新的字符串 result:
48+
- 如果字符是 小写 英文字母,则将其添加到 result 中。
49+
- 字符 '*' 会 删除 result 中的最后一个字符(如果存在)。
50+
- 字符 '#' 会 复制 当前的 result 并追加到其自身后面。
51+
- 字符 '%' 会 反转 当前的 result。
52+
返回最终字符串 result 中第 k 个字符(下标从 0 开始)。如果 k 超出 result 的下标索引范围,则返回 '.'。
53+
提示:
54+
1 <= s.length <= 10^5
55+
s 只包含小写英文字母和特殊字符 '*'、'#' 和 '%'。
56+
0 <= k <= 10^15
57+
处理 s 后得到的 result 的长度不超过 10^15。
58+
59+
逆向思维。
60+
相似题目: 3307. 找出第 K 个字符 II
61+
https://leetcode.cn/problems/find-the-k-th-character-in-string-game-ii/description/
62+
1545. 找出第 N 个二进制字符串中的第 K 位
63+
https://leetcode.cn/problems/find-kth-bit-in-nth-binary-string/
64+
rating 2022 (clist.by)
65+
*/
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import java.util.ArrayList;
2+
import java.util.Arrays;
3+
import java.util.List;
4+
5+
public class Solution3615 {
6+
private char[] s;
7+
private List<Integer>[] g;
8+
private int[][][] memo;
9+
10+
public int maxLen(int n, int[][] edges, String label) {
11+
s = label.toCharArray();
12+
if (edges.length == n * (n - 1) / 2) { // 完全图
13+
int[] cnt = new int[26];
14+
for (char ch : s) {
15+
cnt[ch - 'a']++;
16+
}
17+
int ans = 0, odd = 0;
18+
for (int c : cnt) {
19+
ans += c - c % 2;
20+
odd |= c % 2;
21+
}
22+
return ans + odd;
23+
}
24+
25+
g = new ArrayList[n];
26+
Arrays.setAll(g, e -> new ArrayList<>());
27+
for (int[] e : edges) {
28+
int x = e[0];
29+
int y = e[1];
30+
g[x].add(y);
31+
g[y].add(x);
32+
}
33+
34+
memo = new int[n][n][1 << n];
35+
for (int i = 0; i < n; i++) {
36+
for (int j = 0; j < n; j++) {
37+
Arrays.fill(memo[i][j], -1);
38+
}
39+
}
40+
41+
int ans = 0;
42+
for (int x = 0; x < n; x++) {
43+
// 奇回文串,x 作为回文中心
44+
ans = Math.max(ans, dfs(x, x, 1 << x) + 1);
45+
if (ans == n) {
46+
return n;
47+
}
48+
// 偶回文串,x 和 x 的邻居 y 作为回文中心
49+
for (int y : g[x]) {
50+
// 保证 x < y,减少状态个数和计算量
51+
if (x < y && s[x] == s[y]) {
52+
ans = Math.max(ans, dfs(x, y, 1 << x | 1 << y) + 2);
53+
if (ans == n) {
54+
return n;
55+
}
56+
}
57+
}
58+
}
59+
return ans;
60+
}
61+
62+
// 计算从 x 和 y 向两侧扩展,最多还能访问多少个节点(不算 x 和 y)
63+
private int dfs(int x, int y, int vis) {
64+
if (memo[x][y][vis] != -1) return memo[x][y][vis];
65+
int res = 0;
66+
for (int v : g[x]) {
67+
if ((vis >> v & 1) > 0) { // v 在路径中
68+
continue;
69+
}
70+
for (int w : g[y]) {
71+
if ((vis >> w & 1) == 0 && w != v && s[w] == s[v]) {
72+
// 保证 v < w,减少状态个数和计算量
73+
int r = dfs(Math.min(v, w), Math.max(v, w), vis | 1 << v | 1 << w);
74+
res = Math.max(res, r + 2);
75+
}
76+
}
77+
}
78+
return memo[x][y][vis] = res; // 记忆化
79+
}
80+
}
81+
/*
82+
3615. 图中的最长回文路径
83+
https://leetcode.cn/problems/longest-palindromic-path-in-graph/description/
84+
85+
第 458 场周赛 T4。
86+
87+
给你一个整数 n 和一个包含 n 个节点的 无向图 ,节点编号从 0 到 n - 1,以及一个二维数组 edges,其中 edges[i] = [ui, vi] 表示节点 ui 和节点 vi 之间有一条边。
88+
同时给你一个长度为 n 的字符串 label,其中 label[i] 是与节点 i 关联的字符。
89+
你可以从任意节点开始,移动到任意相邻节点,每个节点 最多 访问一次。
90+
返回通过访问一条路径,路径中 不包含重复 节点,所能形成的 最长回文串 的长度。
91+
回文串 是指正着读和反着读相同的字符串。
92+
提示:
93+
1 <= n <= 14
94+
n - 1 <= edges.length <= n * (n - 1) / 2
95+
edges[i] == [ui, vi]
96+
0 <= ui, vi <= n - 1
97+
ui != vi
98+
label.length == n
99+
label 只包含小写英文字母。
100+
不存在重复边。
101+
102+
中心扩展法 + 状压 DP + 优化 https://leetcode.cn/problems/longest-palindromic-path-in-graph/solutions/3722469/zhong-xin-kuo-zhan-fa-zhuang-ya-dp-by-en-ai9s/
103+
时间复杂度:O(n^4 * 2^n)
104+
rating 2492 (clist.by)
105+
*/
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 Solution3612Tests {
5+
private final Solution3612 solution3612 = new Solution3612();
6+
7+
@Test
8+
public void example1() {
9+
String s = "a#b%*";
10+
String expected = "ba";
11+
Assertions.assertEquals(expected, solution3612.processStr(s));
12+
}
13+
14+
@Test
15+
public void example2() {
16+
String s = "z*#";
17+
String expected = "";
18+
Assertions.assertEquals(expected, solution3612.processStr(s));
19+
}
20+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution3613Tests {
5+
private final Solution3613 solution3613 = new Solution3613();
6+
7+
@Test
8+
public void example1() {
9+
int n = 5;
10+
int[][] edges = UtUtils.stringToInts2("[[0,1,4],[1,2,3],[1,3,2],[3,4,6]]");
11+
int k = 2;
12+
int expected = 4;
13+
Assertions.assertEquals(expected, solution3613.minCost(n, edges, k));
14+
}
15+
16+
@Test
17+
public void example2() {
18+
int n = 4;
19+
int[][] edges = UtUtils.stringToInts2("[[0,1,5],[1,2,5],[2,3,5]]");
20+
int k = 1;
21+
int expected = 5;
22+
Assertions.assertEquals(expected, solution3613.minCost(n, edges, k));
23+
}
24+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution3614Tests {
5+
private final Solution3614 solution3614 = new Solution3614();
6+
7+
@Test
8+
public void example1() {
9+
String s = "a#b%*";
10+
long k = 1;
11+
char expected = 'a';
12+
Assertions.assertEquals(expected, solution3614.processStr(s, k));
13+
}
14+
15+
@Test
16+
public void example2() {
17+
String s = "cd%#*#";
18+
long k = 3;
19+
char expected = 'd';
20+
Assertions.assertEquals(expected, solution3614.processStr(s, k));
21+
}
22+
23+
@Test
24+
public void example3() {
25+
String s = "z*#";
26+
long k = 0;
27+
char expected = '.';
28+
Assertions.assertEquals(expected, solution3614.processStr(s, k));
29+
}
30+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution3615Tests {
5+
private final Solution3615 solution3615 = new Solution3615();
6+
7+
@Test
8+
public void example1() {
9+
int n = 3;
10+
int[][] edges = UtUtils.stringToInts2("[[0,1],[1,2]]");
11+
String label = "aba";
12+
int expected = 3;
13+
Assertions.assertEquals(expected, solution3615.maxLen(n, edges, label));
14+
}
15+
16+
@Test
17+
public void example2() {
18+
int n = 3;
19+
int[][] edges = UtUtils.stringToInts2("[[0,1],[0,2]]");
20+
String label = "abc";
21+
int expected = 1;
22+
Assertions.assertEquals(expected, solution3615.maxLen(n, edges, label));
23+
}
24+
25+
@Test
26+
public void example3() {
27+
int n = 4;
28+
int[][] edges = UtUtils.stringToInts2("[[0,2],[0,3],[3,1]]");
29+
String label = "bbac";
30+
int expected = 3;
31+
Assertions.assertEquals(expected, solution3615.maxLen(n, edges, label));
32+
}
33+
}

0 commit comments

Comments
(0)

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