AtCoder Beginner Contest 212【A - E】

比赛链接:https://atcoder.jp/contests/abc212/tasks

A - Alloy

代码

#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;
}

B - Weak Password

代码

#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;
}

C - Min Difference

代码

#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;
}

D - Querying Multiset

题解

考虑相对大小。

代码

#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;
}

E - Safety Journey

题意

从一个含有 \(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

上一篇:Unity3D学习笔记(三十六):Shader着色器(3)- 光照


下一篇:LeetCode 第 212 场周赛