A. Leap Year
模拟
代码实现
import calendar y = int(input()) if calendar.isleap(y): print(366) else: print(365)
B. Second Best
模拟
代码实现
n = int(input()) a = list(map(int, input().split())) print(a.index(sorted(a)[-2])+1)
C. Transportation Expenses
二分
代码实现
#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; ll m; cin >> n >> m; vector<int> a(n); rep(i, n) cin >> a[i]; auto f = [&](int x) { ll s = 0; rep(i, n) s += min(x, a[i]); return s <= m; }; const int INF = 1001001001; if (f(INF)) puts("infinite"); else { int ac = 0, wa = INF; while (abs(ac-wa) > 1) { int wj = (ac+wa)/2; if (f(wj)) ac = wj; else wa = wj; } cout << ac << '\n'; } return 0; }
D. AtCoder Janken 3
如果你考虑“从前到后遍历能赢就赢”的贪心的话,会发现过不了样例3
考虑dp
记 dp[i][j]
表示到第 次操作为止且最后一次出的是 时所能获胜的最大次数
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; int main() { int n; string s; cin >> n >> s; const int INF = 1001001001001; vector dp(n+1, vector<int>(3, -INF)); rep(i, 3) dp[0][i] = 0; for (int i = 1; i <= n; ++i) { int x = 0; if (s[i-1] == 'R') x = 0; if (s[i-1] == 'P') x = 1; if (s[i-1] == 'S') x = 2; rep(j, 3) { int val = 0; if (j == (x+1)%3) val = 1; if (j == (x+2)%3) continue; rep(pj, 3) { if (j == pj) continue; dp[i][j] = max(dp[i][j], dp[i-1][pj]+val); } } } int ans = ranges::max(dp[n]); cout << ans << '\n'; return 0; }
E. Xor Sigma Problem
按位算贡献,具体分析见 题解
代码实现
#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]; vector<int> s(n+1); rep(i, n) s[i+1] = s[i]^a[i]; ll ans = 0; rep(k, 30) { int one = 0; rep(i, n+1) if (s[i]>>k&1) one++; ans += one*ll(n+1-one)*(1ll<<k); } rep(i, n) ans -= a[i]; cout << ans << '\n'; return 0; }
F. Takahashi on Grid
假设从 出发,走到 时 的最少移动次数以及对应的 坐标分别为 和 ,那么 和 的复合可以在 的时间计算得到,然后上线段树。
G. AtCoder Office
根号分治
先假设一个阈值 ,再令第 个人对应的区间个数为
容易看出所有人的总的区间个数最多为 个
当 且 时,可以直接暴力双指针做,时间复杂度为 ,参考 LC986
当 和 中有一个区间的长度 ,不失一般性地,我们假设 的长度大于 ,那么这样的 显然不超过 个
然后做一下预处理,记 f(i, j)
表示询问 的答案,其中 ,暴力转移可以在 时间内完成
根据均值不等式可知,,等式成立当且仅当
代码实现
#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; cin >> n >> m; vector<P> records; vector<vector<int>> ts(n); rep(i, m) { int t, p; cin >> t >> p; --p; records.emplace_back(t, p); ts[p].push_back(t); } vector<bool> many(n); rep(i, n) many[i] = ts[i].size() > 400; vector<vector<int>> d(n); rep(i, n) if (many[i]) { d[i] = vector<int>(n); int s = 0, pt = 0; bool in = false; vector<int> sign(n, -1); for (auto [t, p] : records) { if (in) s += t-pt; if (p == i) { in = !in; } else { d[i][p] += s*sign[p]; sign[p] *= -1; } pt = t; } } int q; cin >> q; rep(qi, q) { int a, b; cin >> a>> b; --a; --b; if (many[b]) swap(a, b); int ans = 0; if (many[a]) ans = d[a][b]; else { bool ain = false, bin = false; int ai = 0, bi = 0, pt = 0; while (ai < ts[a].size() and bi < ts[b].size()) { int ta = ts[a][ai], tb = ts[b][bi]; int t = min(ta, tb); if (ain and bin) ans += t-pt; pt = t; if (ta < tb) ++ai, ain = !ain; else ++bi, bin = !bin; } } cout << ans << '\n'; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】