From 99ab845e756463334222fb7c874e56947c360470 Mon Sep 17 00:00:00 2001 From: Shadow <15656193+shadowatomic@user.noreply.gitee.com> Date: Fri, 17 Oct 2025 00:27:24 +0800 Subject: [PATCH 1/2] =?UTF-8?q?20251017=E7=AC=AC=E4=B8=80=E6=AC=A1?= =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ..._\351\203\221\346\235\203\345\263\260.cpp" | 23 +++ ..._\351\203\221\346\235\203\345\263\260.cpp" | 133 ++++++++++++++++++ ..._\351\203\221\346\235\203\345\263\260.cpp" | 69 +++++++++ 3 files changed, 225 insertions(+) create mode 100644 "exercise/LC2598_\351\203\221\346\235\203\345\263\260.cpp" create mode 100644 "topic04/submit/LC1377_\351\203\221\346\235\203\345\263\260.cpp" create mode 100644 "topic04/submit/LC1443_\351\203\221\346\235\203\345\263\260.cpp" diff --git "a/exercise/LC2598_\351\203\221\346\235\203\345\263\260.cpp" "b/exercise/LC2598_\351\203\221\346\235\203\345\263\260.cpp" new file mode 100644 index 0000000..ce4ea93 --- /dev/null +++ "b/exercise/LC2598_\351\203\221\346\235\203\345\263\260.cpp" @@ -0,0 +1,23 @@ +#include +using namespace std; + +// 【题目】LC2598.执行操作后的最大MEX +// 【难度】中等 +// 【提交】2025.10.17 https://leetcode.cn/problems/smallest-missing-non-negative-integer-after-operations/submissions/671181704 +// 【标签】贪心、数组、哈希表、数学、第337场周赛 + +class Solution { +public: + int findSmallestInteger(vector& nums, int value) { + vector vec(value); + for(int x : nums){ + vec[(x % value + value) % value]++; + } + int res = 0; + while(vec[res % value] > 0){ + vec[res % value]--; + res++; + } + return res; + } +}; diff --git "a/topic04/submit/LC1377_\351\203\221\346\235\203\345\263\260.cpp" "b/topic04/submit/LC1377_\351\203\221\346\235\203\345\263\260.cpp" new file mode 100644 index 0000000..c898ac7 --- /dev/null +++ "b/topic04/submit/LC1377_\351\203\221\346\235\203\345\263\260.cpp" @@ -0,0 +1,133 @@ +#include +using namespace std; + +// 【题目】LC1377.T秒后青蛙的位置 +// 【难度】困难 +// 【提交】2025.10.17 https://leetcode.cn/problems/frog-position-after-t-seconds/submissions/671200553 +// 【标签】树、深度优先搜索、广度优先搜索、图、第179场周赛 + +// 方法1:BFS +class Solution { +public: + double frogPosition(int n, vector>& edges, int t, int target) { + vector> g(n + 1); + for(auto& edge : edges){ + g[edge[0]].emplace_back(edge[1]); + g[edge[1]].emplace_back(edge[0]); + } + + queue> qu; + qu.emplace(1, -1, 0, 1); + while(qu.size()){ + auto [to, from, time, prob] = qu.front(); + qu.pop(); + + if(time == t && to == target){ + return prob; + } + + if(time > t) continue; + + int cnt = g[to].size() - 1; + if(from == -1) cnt++; + + if(cnt == 0){ + if(t >= time && to == target) return prob; + continue; + } + + for(int x : g[to]){ + if(x == from) continue; + qu.emplace(x, to, time + 1, prob * 1.0 / cnt); + } + } + return 0; + } +}; + +// 方法2:DFS +class Solution { +public: + double frogPosition(int n, vector>& edges, int t, int target) { + vector> g(n + 1); + for(auto& edge : edges){ + g[edge[0]].emplace_back(edge[1]); + g[edge[1]].emplace_back(edge[0]); + } + vector visited(n + 1, false); + return dfs(g, visited, 1, t, target); + } + + double dfs(vector>& g, vector& visited, int cur, int t, int target){ + double ans = 0.0; + int cnt = cur == 1 ? g[cur].size() : g[cur].size() - 1; + if(t == 0 || cnt == 0){ + return target == cur ? 1.0 : 0.0; + } + + visited[cur] = true; + for(int x : g[cur]){ + if(!visited[x]){ + ans += dfs(g, visited, x, t - 1, target); + } + } + return ans / cnt; + } +}; + +// 方法3:自顶向下(递) 执行用时:0 ms | 击败 100% +class Solution { +public: + double frogPosition(int n, vector>& edges, int t, int target) { + vector> g(n + 1); + g[1].emplace_back(0); + for(auto& edge : edges){ + g[edge[0]].emplace_back(edge[1]); + g[edge[1]].emplace_back(edge[0]); + } + double ans = 0; + function dfs = [&](int cur, int parent, int time, long long product) -> bool { + if(cur == target && (time == 0 || g[cur].size() == 1)){ + ans = 1.0 / product; + return true; + } + if(cur == target || g[cur].size() == 1 || time == 0) return false; + for(int x : g[cur]){ + if(x != parent && dfs(x, cur, time - 1, product * (g[cur].size() - 1))){ + return true; + } + } + return false; + }; + + dfs(1, 0, t, 1); + return ans; + } +}; + +// 方法4:自顶向下(归) 执行用时:0 ms | 击败 100% +using ll = long long; +class Solution { +public: + double frogPosition(int n, vector>& edges, int t, int target) { + vector> g(n + 1); + g[1].emplace_back(0); + for(auto& edge : edges){ + g[edge[0]].emplace_back(edge[1]); + g[edge[1]].emplace_back(edge[0]); + } + + function dfs = [&](int cur, int parent, int time) -> ll { + if(time == 0) return cur == target; + if(cur == target) return g[cur].size() == 1; + for(int x : g[cur]){ + if(x == parent) continue; + ll product = dfs(x, cur, time - 1); + if(product) return product * (g[cur].size() - 1); + } + return 0; + }; + ll product = dfs(1, 0, t); + return product ? 1.0 / product : 0; + } +}; diff --git "a/topic04/submit/LC1443_\351\203\221\346\235\203\345\263\260.cpp" "b/topic04/submit/LC1443_\351\203\221\346\235\203\345\263\260.cpp" new file mode 100644 index 0000000..6c86d77 --- /dev/null +++ "b/topic04/submit/LC1443_\351\203\221\346\235\203\345\263\260.cpp" @@ -0,0 +1,69 @@ +#include +using namespace std; + +// 【题目】LC1443.收集树上所有苹果的最少时间 +// 【难度】中等 +// 【提交】2025.10.17 https://leetcode.cn/problems/minimum-time-to-collect-all-apples-in-a-tree/submissions/671164057 +// 【标签】树、深度优先搜索、广度优先搜索、哈希表、第188场周赛 + +class Solution { + int ans; +public: + int geyAppleNumber(int to, int from, vector& hasApple, vector>& g, vector& apple){ + apple[to] = hasApple[to]; + for(int x : g[to]){ + if(x == from) continue; + apple[to] += geyAppleNumber(x, to, hasApple, g, apple); + } + return apple[to]; + } + + void dfs(int to, int from, vector>& g, vector& apple){ + for(int x : g[to]){ + if(x == from) continue; + if(apple[x]){ + ans += 2; + dfs(x, to, g, apple); + } + } + } + + int minTime(int n, vector>& edges, vector& hasApple) { + vector> g(n); + for(auto& edge : edges){ + g[edge[0]].emplace_back(edge[1]); + g[edge[1]].emplace_back(edge[0]); + } + vector apple(n, 0); + geyAppleNumber(0, -1, hasApple, g, apple); + dfs(0, -1, g, apple); + return ans; + } +}; + +// 方法2; +class Solution { +public: + int minTime(int n, vector>& edges, vector& hasApple) { + vector> g(n); + for(auto& edge : edges){ + g[edge[0]].emplace_back(edge[1]); + g[edge[1]].emplace_back(edge[0]); + } + function(int, int)> dfs = [&](int to, int from) -> tuple { + int total = 0; + bool flag = hasApple[to]; + for(int x : g[to]){ + if(x == from) continue; + auto it = dfs(x, to); + total += get<1>(it); + flag |= get<0>(it); + } + if(flag){ + return {true, total + 2}; + } else return {false, 0}; + }; + auto [x, y] = dfs(0, -1); + return x ? y - 2: 0; + } +}; -- Gitee From dae0638c5fbd0a74361d3d59b862c333d8517088 Mon Sep 17 00:00:00 2001 From: Shadow <15656193+shadowatomic@user.noreply.gitee.com> Date: Fri, 17 Oct 2025 22:06:14 +0800 Subject: [PATCH 2/2] =?UTF-8?q?20251017=E7=AC=AC=E4=B8=80=E6=AC=A1?= =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ..._\351\203\221\346\235\203\345\263\260.cpp" | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 "exercise/LC3003_\351\203\221\346\235\203\345\263\260.cpp" diff --git "a/exercise/LC3003_\351\203\221\346\235\203\345\263\260.cpp" "b/exercise/LC3003_\351\203\221\346\235\203\345\263\260.cpp" new file mode 100644 index 0000000..5e0c0ff --- /dev/null +++ "b/exercise/LC3003_\351\203\221\346\235\203\345\263\260.cpp" @@ -0,0 +1,151 @@ +#include +using namespace std; + +// 【题目】LC3003.执行操作后的最大分割数量 +// 【难度】困难 +// 【提交】2025.10.17 https://leetcode.cn/problems/maximize-the-number-of-partitions-after-operations/submissions/671470182 +// 【标签】位运算、字符串、动态规划、状态压缩、第379场周赛 + +// 方法1:前后缀和分解 +class Solution { +public: + int maxPartitionsAfterOperations(string s, int k) { + if(k == 26) return 1; + int seg = 1, mask = 0, size = 0; + + auto update = [&](int i) -> void { + int bit = 1 << (s[i] - 'a'); + if(mask & bit) return; + if(size + 1 > k){ + seg++; + mask = bit; + size = 1; + } else { + mask |= bit; + size++; + } + }; + + int n = s.length(); + vector> suf(n + 1); + + for(int i = n - 1; i >= 0; i--){ + update(i); + suf[i] = {seg, mask}; + } + + int ans = seg; + seg = 1, mask = 0, size = 0; + for(int i = 0; i < n; i++){ + auto [suf_seg, suf_mask] = suf[i + 1]; + int res = seg + suf_seg; + int union_size = popcount((uint32_t)(mask | suf_mask)); + if(union_size < k) res--; + else if(union_size < 26 && size == k && popcount((uint32_t)suf_mask) == k) res++; + ans = max(ans, res); + update(i); + } + return ans; + } +}; + +// 方法2:位运算 + 前后缀和预处理 + 枚举 +class Solution { +public: + int maxPartitionsAfterOperations(string s, int k) { + int n = s.length(); + vector> left(n), right(n); + int num = 0, mask = 0, cnt = 0; + for(int i = 0; i < n - 1; i++){ + int binary = 1 << (s[i] - 'a'); + if(!(mask & binary)){ + cnt++; + if(cnt <= k){ + mask |= binary; + } else { + num++; + mask = binary; + cnt = 1; + } + } + get<0>(left[i + 1]) = num; + get<1>(left[i + 1]) = mask; + get<2>(left[i + 1]) = cnt; + } + + num = 0, mask = 0, cnt = 0; + for(int i = n - 1; i > 0; i--){ + int binary = 1 << (s[i] - 'a'); + if(!(mask & binary)){ + if(cnt + 1 <= k){ + cnt++; + mask |= binary; + } else { + num++; + mask = binary; + cnt = 1; + } + } + get<0>(right[i - 1]) = num; + get<1>(right[i - 1]) = mask; + get<2>(right[i - 1]) = cnt; + } + + int res = 0; + for(int i = 0; i < n; i++){ + int mask = get<1>(left[i]) | get<1>(right[i]); + int seg = get<0>(left[i]) + get<0>(right[i]) + 2; + int cnt = 0; + while(mask){ + mask = mask & (mask - 1); + cnt++; + } + if(get<2>(left[i]) == k && get<2>(right[i]) == k && cnt < 26){ + seg++; + } else if (min(cnt + 1, 26) <= k) seg--; + res = max(res, seg); + } + return res; + } +}; + +// 方法3:记忆化搜索 (执行时间: 0ms | 击败100%) +const auto _ = std::cin.tie(nullptr) -> sync_with_stdio(false); +using ll = long long; +class Solution { +public: + int maxPartitionsAfterOperations(string s, int k) { + int n = s.length(); + unordered_map memo; + + auto dfs = [&](this auto&& dfs, int cur, int mask, bool changed) -> int { + if(cur == n) return 1; + ll argument = (ll)cur << 32 | mask << 1 | changed; + auto it = memo.find(argument); + if(it != memo.end()){ + return it -> second; + } + + int res = 0; + int bit = 1 << (s[cur] - 'a'); + int new_mask = mask | bit; + if(popcount((uint32_t)new_mask) > k){ + res = dfs(cur + 1, bit, changed) + 1; + } else res = dfs(cur + 1, new_mask, changed); + + if(!changed){ + for(int j = 0; j < 26; j++){ + new_mask = mask | (1 << j); + if(popcount((uint32_t)new_mask) > k){ + res = max(res, dfs(cur + 1, 1 << j, true) + 1); + } else { + res = max(res, dfs(cur + 1, new_mask, true)); + } + } + } + return memo[argument] = res; + }; + + return dfs(0, 0, false); + } +}; -- Gitee