A. 369
在 和 之间可以插一个数构成等差数列当且仅当 是偶数
特例:,此时答案是
代码实现
a, b = map(int, input().split()) if a == b: print(1) elif (a+b)%2 == 0: print(3) else: print(2)
B. Piano 3
把左手和右手分别放在对应的最左侧然后按顺序模拟即可
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; int main() { int n; cin >> n; int ans = 0; int l = -1, r = -1; rep(i, n) { int a; char s; cin >> a >> s; if (s == 'L') { if (l != -1) ans += abs(l-a); l = a; } else { if (r != -1) ans += abs(r-a); r = a; } } cout << ans << '\n'; return 0; }
C. Count Arithmetic Subarrays
双指针
代码实现
#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; cin >> n; vector<int> a(n); rep(i, n) cin >> a[i]; ll ans = 0; int r = 0; rep(l, n) { while (r < n) { if (r > l+1 and a[r]-a[r-1] != a[r-1]-a[r-2]) break; ++r; } ans += r-l; } cout << ans << '\n'; return 0; }
D. Bonus EXP
简单dp
记 dp[i][j]
表示到第 只怪兽为止已经打的怪兽的个数 时能获得的最大经验值
时间复杂度为
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; inline void chmax(ll& x, ll y) { if (x < y) x = y; } int main() { int n; cin >> n; vector<int> a(n); rep(i, n) cin >> a[i]; const ll INF = 1e18; vector dp(n+1, vector<ll>(2, -INF)); dp[0][0] = 0; rep(i, n) { int ni = i+1; rep(j, 2) { { // o int nj = j^1; int X = j%2 ? a[i]*2 : a[i]; chmax(dp[ni][nj], dp[i][j]+X); } { // x int nj = j; chmax(dp[ni][nj], dp[i][j]); } } } ll ans = max(dp[n][0], dp[n][1]); cout << ans << '\n'; return 0; }
E. Sightseeing Tour
注意到 这个条件,这道题就做完了
只需枚举这 条边不同的顺序和每条边的方向
暗示我们可以跑
那么复杂度就是
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; using Edge = tuple<int, int, int>; inline void chmin(ll& a, ll b) { if (a > b) a = b; } int main() { int n, m; cin >> n >> m; vector<Edge> es; const ll INF = 1e18; vector dist(n, vector<ll>(n, INF)); rep(i, n) dist[i][i] = 0; rep(i, m) { int a, b, c; cin >> a >> b >> c; --a; --b; es.emplace_back(a, b, c); chmin(dist[a][b], c); chmin(dist[b][a], c); } rep(k, n)rep(i, n)rep(j, n) chmin(dist[i][j], dist[i][k]+dist[k][j]); int q; cin >> q; rep(qi, q) { int k; cin >> k; vector<int> ei(k); rep(i, k) cin >> ei[i], ei[i]--; ll ans = INF; do { rep(s, 1<<k) { ll now = 0; int v = 0; rep(i, k) { auto [a, b, c] = es[ei[i]]; if (s>>i&1) swap(a, b); now += dist[v][a]; now += c; v = b; } now += dist[v][n-1]; chmin(ans, now); } } while (next_permutation(ei.begin(), ei.end())); cout << ans << '\n'; } return 0; }
F. Gather Coins
这题本质上就是求二维上升子序列
可以用扫描线和线段树加速
代码实现
#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 P = pair<int, int>; P op(P a, P b) { return max(a, b); } P e() { return P(0, -1); } int main() { int h, w, n; cin >> h >> w >> n; vector<P> coins; rep(i, n) { int r, c; cin >> r >> c; coins.emplace_back(r, c); } ranges::sort(coins); const int MX = 200005; segtree<P, op, e> t(MX); vector<int> pre(n); rep(i, n) { int y = coins[i].second; auto [lis, idx] = t.prod(0, y+1); pre[i] = idx; t.set(y, P(lis+1, i)); } string ans; int r = h, c = w; auto mv = [&](P p) { auto [nr, nc] = p; while (r > nr) r--, ans += 'D'; while (c > nc) c--, ans += 'R'; }; auto [lis, i] = t.all_prod(); while (i != -1) { mv(coins[i]); i = pre[i]; } mv(P(1, 1)); ranges::reverse(ans); cout << lis << '\n'; cout << ans << '\n'; return 0; }
G. As far as possible
可以发现答案就是由点 和指定的 个点构成的树形图上每条边的边权 的总和
青木为了让答案最大,应该尽可能地选距离点 更远的叶子节点,等选完叶子节点以后,剩下的答案保持不变
那么怎么来求答案呢?
- 树形dp+multiset做dsu on tree
我们可以对树上每个点维护一个可重集,对于 这条边,边权为 ,取出点 的可重集中的最大值 ,同时将这个最大值在点 的可重集中删去,然后将 加入点 的可重集中
具体分析可以参考 的题解
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; struct Edge { int to, cost; Edge() {} Edge(int to, int cost): to(to), cost(cost) {} }; int main() { int n; cin >> n; vector<vector<Edge>> g(n); rep(i, n-1) { int a, b, c; cin >> a >> b >> c; --a; --b; g[a].emplace_back(b, c); g[b].emplace_back(a, c); } auto dfs = [&](auto& dfs, int v, int p=-1) -> multiset<ll> { multiset<ll> f; for (auto [u, w] : g[v]) { if (u == p) continue; auto nf = dfs(dfs, u, v); ll x = *nf.rbegin(); nf.erase(prev(nf.end())); nf.insert(x+w); if (f.size() < nf.size()) swap(f, nf); f.merge(nf); } f.insert(0); return f; }; auto f = dfs(dfs, 0); vector<ll> as; for (ll x : f) as.push_back(x); ranges::reverse(as); ll ans = 0; for (ll a : as) { cerr << a << '\n'; ans += a*2; cout << ans << '\n'; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现