A. Full House 2
只需判定 中是否只有 种数
代码实现
print('Yes' if len(set(map(int, input().split()))) == 2 else 'No')
B. Calculator
模拟
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; int main() { string s; cin >> s; int n = s.size(); int ans = n; rep(i, n) { if (s.substr(i, 2) == "00") { ans--; s[i] = 'X'; s[i+1] = 'X'; } } cout << ans << '\n'; return 0; }
C. Operate 1
注意到对 删除一个字符使得它能和 匹配,等价于对 添加一个字符使得它能和 匹配,所以我们只需交换 和 ,让 变成较长串即可
然后计算 和 的最长公共前缀和最长公共后缀,判定二者的累积和是否大于等于 的长度,再加上 的长度是否等于 的长度加 ,就能得出是否能通过对 删掉一个字符得到
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; bool solve() { int k; string s, t; cin >> k >> s >> t; if (s == t) return true; if (s.size() == t.size()) { int cnt = 0; rep(i, s.size()) { if (s[i] != t[i]) cnt++; } return cnt <= 1; } if (s.size() < t.size()) swap(s, t); if (s.size() != t.size()+1) return false; int maxL = 0, maxR= 0; rep(i, t.size()) { if (s[i] != t[i]) break; maxL++; } for (int i = t.size()-1; i >= 0; --i) { if (s[i+1] != t[i]) break; maxR++; } return maxL+maxR >= t.size(); } int main() { if (solve()) puts("Yes"); else puts("No"); return 0; }
D. Diagonal Separation
容易发现如果有解的话,每个黑色格子左上方都是黑色格子,且每个白色格子右下方都是白色格子
可以考虑按 轴从后往前扫描,同时更新黑色格子的最大的 坐标(记做 ),如果当前扫描到的是白色格子,那么如果它的 坐标 的话,就说明这个白色格子右下方有黑色格子,所以无解
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; int main() { int n, m; cin >> n >> m; vector<tuple<int, int, char>> points; rep(i, m) { int x, y; char c; cin >> x >> y >> c; points.emplace_back(x, y, c); } ranges::sort(points, greater<>()); int maxY = -1; for (auto [x, y, c] : points) { if (c == 'B') { maxY = max(maxY, y); } else { if (y <= maxY) { puts("No"); return 0; } } } puts("Yes"); return 0; }
E. Maximize XOR
注意到 ,这个限制条件保证了可以用爆搜来解决
然后减减枝就行,当剩下要选的数的个数等于接下来没扫描过的数,那么意味着要把这些数全部选上才行,那么我们可以先预处理出序列的后缀异或和即可
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; int main() { int n, k; cin >> n >> k; vector<ll> a(n); rep(i, n) cin >> a[i]; vector<ll> s(n+1); for (int i = n-1; i >= 0; --i) s[i] = s[i+1]^a[i]; ll ans = 0; auto dfs = [&](auto& f, int i, int k, ll x) -> void { if (k == 0) { ans = max(ans, x); return; } if (k == n-i) { ans = max(ans, x^s[i]); return; } f(f, i+1, k, x); f(f, i+1, k-1, x^a[i]); }; dfs(dfs, 0, k, 0); cout << ans << '\n'; return 0; }
F. Operate K
其实就是编辑距离
记 dp[i][j]
表示使得 和 匹配的最小操作次数
时间复杂度为
但注意到当 时的编辑距离一定大于 ,所以只需要考虑 的情况。那么复杂度就变成了
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; inline void chmin(int& x, int y) { if (x > y) x = y; } int main() { int k; string s, t; cin >> k >> s >> t; int n = s.size(), m = t.size(); if (abs(n-m) > k) { puts("No"); return 0; } const int INF = 1001001001; vector dp(n+1, vector<int>(k*2+1, INF)); auto upd = [&](int i, int j, int x) { int e = j-i; // j = i+e if (e < -k or e > k) return; chmin(dp[i][e+k], x); }; upd(0, 0, 0); // i = j = 0 rep(i, n+1) { for (int e = -k; e <= k; ++e) { int j = i+e; int now = dp[i][e+k]; if (now == INF) continue; if (i < n) upd(i+1, j, now+1); if (j < m) upd(i, j+1, now+1); if (i < n and j < m) { upd(i+1, j+1, now+1); if (s[i] == t[j]) upd(i+1, j+1, now); } } } if (dp[n][(m-n)+k] <= k) puts("Yes"); else puts("No"); return 0; }
G. Many MST
考虑 Kruskal, 上的边权和等于 ,而 又等于仅保留边权小于 的边所构成的连通块的个数
那么
仅保留边权小于 的边所构成的连通块的个数 仅保留边权小于 的边所构成的连通块的个数
先不考虑 -1
的贡献
仅保留边权小于 的边所构成的连通块的个数等于 包含点 的连通块的大小
记 表示点 所在的连通块的大小为 的方案数
记 dp[i]
表示 个点的连通图有多少种
时间复杂度为
代码实现
#include <bits/stdc++.h> #include <atcoder/all> using namespace atcoder; #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using mint = modint998244353; int c2(int n) { return n*(n-1)/2; } mint comb[505][505]; mint solve(int n, int m, int x) { vector<mint> pow_m(c2(n)+1, 1); rep(i, c2(n)) pow_m[i+1] = pow_m[i]*m; vector<mint> pow_x(c2(n)+1, 1); rep(i, c2(n)) pow_x[i+1] = pow_x[i]*x; vector<mint> dp(n+1); auto f = [&](int n, int k) { // 在n个点的图中恰有k个点连通的方案数 mint res = dp[k]; res *= pow_x[k*(n-k)]; res *= pow_m[c2(n-k)]; res *= comb[n-1][k-1]; return res; }; for (int i = 1; i <= n; ++i) { dp[i] = pow_m[c2(i)]; for (int j = 1; j < i; ++j) dp[i] -= f(i, j); } mint res; for (int i = 1; i <= n; ++i) res += f(n, i)/i; res *= n; res -= pow_m[c2(n)]; return res; } int main() { int n, m; cin >> n >> m; comb[0][0] = 1; rep(i, n)rep(j, i+1) { comb[i+1][j] += comb[i][j]; comb[i+1][j+1] += comb[i][j]; } mint ans; rep(x, m) ans += solve(n, m, m-x); cout << ans.val() << '\n'; return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战