比赛链接:https://atcoder.jp/contests/abc212/tasks
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int a, b; cin >> a >> b; if (a > 0 and b > 0) { cout << "Alloy" << "\n"; } else if (a > 0) { cout << "Gold" << "\n"; } else { cout << "Silver" << "\n"; } return 0; }
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); string s; cin >> s; string t; for (int i = 1; i < 4; i++) { t += '0' + (s[i] - s[i - 1] + 10) % 10; } cout << (t == "000" or t == "111" ? "Weak" : "Strong") << "\n"; return 0; }
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; set<int> a, b; for (int i = 0; i < n; i++) { int x; cin >> x; a.insert(x); } for (int i = 0; i < m; i++) { int x; cin >> x; b.insert(x); } int ans = INT_MAX; for (auto i : a) { auto it = b.lower_bound(i); ans = min(ans, abs(*it - i)); if (it != b.begin()) { ans = min(ans, abs(*prev(it) - i)); } } cout << ans << "\n"; return 0; }
考虑相对大小。
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int q; cin >> q; priority_queue<long long, vector<long long>, greater<long long>> pque; long long delta = 0; while (q--) { int op; cin >> op; if (op == 1) { int x; cin >> x; pque.push(x - delta); } else if (op == 2) { int x; cin >> x; delta += x; } else { cout << pque.top() + delta << "\n"; pque.pop(); } } return 0; }
从一个含有 \(n\) 个结点的完全图中去掉 \(m\) 条边,问长为 \(k\) ,且起点和终点均为结点 \(1\) 的路径个数。
由数据范围猜测应为二维 \(dp\) ,设 \(dp_{ij}\) 为从起点出发,长为 \(i\) ,终点为 \(j\) 的路径个数。
易得状态转移方程为:
vector<vector<int>> dp(k + 1, vector<int> (n)); dp[0][0] = 1; // 初始状态,长为 0 ,从结点 1 出发 for (int i = 0; i < k; i++) { for (int u = 0; u < n; u++) { // 枚举下一层路径长度的终点 for (auto v : G[u]) { // 所有与终点相连的结点都可以转移到该点并使路径长度加一 dp[i + 1][u] += dp[i][v]; } } } cout << dp[k][0] << "\n";
由于边界情况余下边数较多,内两层的循环次数多达 \(10^6\) ,所以不妨考虑不用加法,而是用减法得到下一层的结果。
类比一下就是:
a + b + c + d = e ans = a + b + c // 为某一终点加上所有与之相邻结点的方案数 ans = e - d // 从总方案数中减去所有与该终点不相邻的结点的方案数
状态转移方程为:
vector<vector<int>> dp(k + 1, vector<int> (n)); dp[0][0] = 1; for (int i = 0; i < k; i++) { int sum = accumulate(dp[i].begin(), dp[i].end(), 0); for (int u = 0; u < n; u++) { dp[i + 1][u] = sum; for (auto v : G[u]) { dp[i + 1][u] -= dp[i][v]; } } } cout << dp[k][0] << "\n";
最后可以压缩一下空间复杂度。
#include <bits/stdc++.h> using namespace std; constexpr int MOD = 998244353; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m, k; cin >> n >> m >> k; vector<vector<int>> G(n); for (int u = 0; u < n; u++) { G[u].push_back(u); } for (int i = 0; i < m; i++) { int u, v; cin >> u >> v; --u, --v; G[u].push_back(v); G[v].push_back(u); } vector<int> dp(n); dp[0] = 1; for (int i = 0; i < k; i++) { int sum = accumulate(dp.begin(), dp.end(), 0, [&](int x, int sum) { return (x + sum) % MOD; }); vector<int> next_dp(n); for (int u = 0; u < n; u++) { next_dp[u] = sum; for (auto v : G[u]) { next_dp[u] = (next_dp[u] - dp[v] + MOD) % MOD; } } dp = next_dp; } cout << dp[0] << "\n"; return 0; }
https://atcoder.jp/contests/abc212/submissions/24652558
第一场总共有八题的 ABC ,虽然看起来对我来说是没什么区别啦 =。=
最近的比赛都能看到 tourist ,是放暑假了吗 233