T1:Similar String
模拟
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; char nomalize(char a) { if (a == '1') return 'l'; if (a == '0') return 'o'; return a; } string nomalize(string s) { rep(i, s.size()) s[i] = nomalize(s[i]); return s; } int main() { int n; cin >> n; string s, t; cin >> s >> t; s = nomalize(s); t = nomalize(t); if (s == t) puts("Yes"); else puts("No"); return 0; }
T2:Discord
模拟
代码实现
#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 a(m, vector<int>(n)); rep(i, m)rep(j, n) cin >> a[i][j]; rep(i, m)rep(j, n) a[i][j]--; vector g(n, vector<bool>(n+1)); rep(i, m) { rep(j, n-1) { g[a[i][j]][a[i][j+1]] = true; } } int ans = 0; rep(x, n)rep(y, x) { if (g[x][y] or g[y][x]) continue; ans++; } cout << ans << '\n'; return 0; }
T3:Dash
可以用 std::set
来维护所有恢复体力的药的位置
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using P = pair<int, int>; int main() { int n, m, h, k; cin >> n >> m >> h >> k; string s; cin >> s; set<P> ps; rep(i, m) { int x, y; cin >> x >> y; ps.emplace(x, y); } int x = 0, y = 0; rep(i, n) { if (s[i] == 'R') x++; if (s[i] == 'L') x--; if (s[i] == 'U') y++; if (s[i] == 'D') y--; h--; if (h < 0) { puts("No"); return 0; } if (ps.count(P(x, y))) { if (h < k) { h = k; ps.erase(P(x, y)); } } } puts("Yes"); return 0; }
T4:Shift vs. CapsLock
记 dp[i][c]
表示输入 的前 个字符,且当前 CapsLock 的状态为 c ? ON : OFF
时所需最少用时
代码实现
// 1. 记忆化搜索 #include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; ll dp[300005][2]; bool memo[300005][2]; int main() { int x, y, z; cin >> x >> y >> z; string s; cin >> s; auto f = [&](auto f, int i, int c) -> ll { if (i == s.size()) return 0; if (memo[i][c]) return dp[i][c]; ll res = 1e18; int a = s[i] == 'A' ? 1 : 0; int cost1 = (a == c) ? x : y; int cost2 = z + ((a == c) ? y : x); res = cost1 + f(f, i+1, c); res = min(res, cost2 + f(f, i+1, c^1)); memo[i][c] = true; return dp[i][c] = res; }; cout << f(f, 0, 0) << '\n'; return 0; } // 2. dp #include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; inline void chmin(ll& x, ll y) { if (x > y) x = y; } int main() { int x, y, z; cin >> x >> y >> z; string s; cin >> s; int n = s.size(); const ll INF = 1e18; vector dp(n+1, vector<ll>(2, INF)); dp[0][0] = 0; rep(i, n)rep(c, 2) { int a = s[i] == 'A'; rep (nc, 2) { ll cost = (a == nc) ? x : y; if (c != nc) cost += z; chmin(dp[i+1][nc], dp[i][c] + cost); } } cout << min(dp[n][0], dp[n][1]) << '\n'; return 0; }
T5:A Gift From the Stars
可以考虑从其中一个叶节点出发进行 ,若当前点的深度 ,则当前点是一个星图的中心
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; int main() { int n; cin >> n; vector<vector<int>> to(n); rep(i, n-1) { int a, b; cin >> a >> b; --a; --b; to[a].push_back(b); to[b].push_back(a); } int leaf = -1; rep(i, n) if (to[i].size() == 1) leaf = i; vector<int> ans; auto dfs = [&](auto f, int v, int p=-1, int d=0) -> void { if (d%3 == 1) ans.push_back(to[v].size()); for (int u : to[v]) if (u != p) { f(f, u, v, d+1); } }; dfs(dfs, leaf); sort(ans.begin(), ans.end()); for (int a : ans) cout << a << ' '; return 0; }
T6:Damage over Time
可以从后往前考虑
如果能在 回合以内打到的话,咒文 的总伤害就是 ,所以使用能让这个值最大化的咒文就可以了!
可以将使用相同咒文的回合放在一起计算,从而加速这个过程。
T7:Bags Game
可以考虑区间
记 dp[l][r]
表示两人从区间 开始分别采用最优策略得到的
然后用线段树来加速查询区间最小值即可
代码实现
#include <bits/stdc++.h> #if __has_include(<atcoder/all>) #include <atcoder/all> using namespace atcoder; #endif #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; inline void chmax(ll& a, ll b) { if (a < b) a = b; } const ll INF = 1e18; ll op(ll a, ll b) { return min(a, b); } ll e() { return INF; } int main() { int n, a, b, c, d; cin >> n >> a >> b >> c >> d; vector<int> x(n); rep(i, n) cin >> x[i]; vector<ll> s(n+1); rep(i, n) s[i+1] = s[i]+x[i]; auto sum = [&](int l, int r) { return s[r]-s[l]; }; vector dp(n+1, vector<ll>(n+1, -INF)); rep(i, n+1) dp[i][i] = 0; using seg = segtree<ll, op, e>; vector<seg> t(n+1, seg(n)); for (int w = 1; w <= n; ++w) { rep(l, n) { int r = l+w; if (r > n) break; ll now = -INF; chmax(now, x[l]-dp[l+1][r]); chmax(now, x[r-1]-dp[l][r-1]); auto upd = [&](int a, int b) { if (w <= b) { chmax(now, sum(l, r)-a); } else { ll val = t[w-b].prod(l, l+b+1); chmax(now, sum(l, r)-val-a); } }; upd(a, b); upd(c, d); dp[l][r] = now; t[w].set(l, now+sum(l, r)); } } cout << dp[0][n] << '\n'; return 0; }
T8:Constrained Tree Degree
可以考虑 prufer序列
结论:
顶点 为 的生成树有 种
我们需要求的是
可以适当做一下变形,
其中, 这一部分可以转成指数型生成函数求解
记
那么,最后的答案就是
代码实现
#include <bits/stdc++.h> #if __has_include(<atcoder/all>) #include <atcoder/all> using namespace atcoder; #endif #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using mint = modint998244353; // combination mod prime struct modinv { int n; vector<mint> d; modinv(): n(2), d({0,1}) {} mint operator()(int i) { while (n <= i) d.push_back(-d[mint::mod()%n]*(mint::mod()/n)), ++n; return d[i]; } mint operator[](int i) const { return d[i];} } invs; struct modfact { int n; vector<mint> d; modfact(): n(2), d({1,1}) {} mint operator()(int i) { while (n <= i) d.push_back(d.back()*n), ++n; return d[i]; } mint operator[](int i) const { return d[i];} } facts; struct modfactinv { int n; vector<mint> d; modfactinv(): n(2), d({1,1}) {} mint operator()(int i) { while (n <= i) d.push_back(d.back()*invs(n)), ++n; return d[i]; } mint operator[](int i) const { return d[i];} } ifacts; mint comb(int n, int k) { if (n < k || k < 0) return 0; return facts(n)*ifacts(k)*ifacts(n-k); } // Formal Power Series using vm = vector<mint>; struct fps : vm { #define d (*this) #define s int(vm::size()) template<class...Args> fps(Args...args): vm(args...) {} fps(initializer_list<mint> a): vm(a.begin(),a.end()) {} void rsz(int n) { if (s < n) resize(n);} fps& low_(int n) { resize(n); return d;} fps low(int n) const { return fps(d).low_(n);} mint& operator[](int i) { rsz(i+1); return vm::operator[](i);} mint operator[](int i) const { return i<s ? vm::operator[](i) : 0;} mint operator()(mint x) const { mint r; for (int i = s-1; i >= 0; --i) r = r*x+d[i]; return r; } fps operator-() const { fps r(d); rep(i,s) r[i] = -r[i]; return r;} fps& operator+=(const fps& a) { rsz(a.size()); rep(i,a.size()) d[i] += a[i]; return d;} fps& operator-=(const fps& a) { rsz(a.size()); rep(i,a.size()) d[i] -= a[i]; return d;} fps& operator*=(const fps& a) { return d = convolution(d, a);} fps& operator*=(mint a) { rep(i,s) d[i] *= a; return d;} fps& operator/=(mint a) { rep(i,s) d[i] /= a; return d;} fps operator+(const fps& a) const { return fps(d) += a;} fps operator-(const fps& a) const { return fps(d) -= a;} fps operator*(const fps& a) const { return fps(d) *= a;} fps operator*(mint a) const { return fps(d) *= a;} fps operator/(mint a) const { return fps(d) /= a;} fps operator~() const { fps r({d[0].inv()}); for (int i = 1; i < s; i <<= 1) r = r*mint(2) - (r*r*low(i<<1)).low(i<<1); return r.low_(s); } fps& operator/=(const fps& a) { int w = s; d *= ~a; return d.low_(w);} fps operator/(const fps& a) const { return fps(d) /= a;} fps integ() const { fps r; rep(i,s) r[i+1] = d[i]/(i+1); return r; } fps pow(int t) { if (t == 1) return *this; fps r = pow(t>>1); (r *= r).low_(s); if (t&1) (r *= *this).low_(s); return r; } #undef s #undef d }; ostream& operator<<(ostream&o,const fps&a) { rep(i,a.size()) o<<(i?" ":"")<<a[i].val(); return o; } int main() { cin.tie(nullptr) -> sync_with_stdio(false); int n, k; cin >> n >> k; int m = n*2-2; fps f(m+1); rep(i, k) { int s; cin >> s; f[s] = ifacts(s-1); } f.pow(n); mint ans = f.pow(n)[m]*facts(n-2); cout << ans.val() << '\n'; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现