zoukankan      html  css  js  c++  java
  • AISing Programming Contest 2021(AtCoder Beginner Contest 202)

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

    A - Three Dice

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int a, b, c;
        cin >> a >> b >> c;
        cout << 21 - a - b - c << "
    ";
        return 0;
    }
    

    B - 180°

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        string s;
        cin >> s;
        reverse(s.begin(), s.end());
        for (auto& ch : s) {
            if (ch == '6') {
                ch = '9';
            } else if (ch == '9') {
                ch = '6';
            }
        }
        cout << s << "
    ";
        return 0;
    }
    

    C - Made Up

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n;
        cin >> n;
        vector<int> a(n), b(n), c(n);
        for (int i = 0; i < n; i++) {
            cin >> a[i];
        }
        for (int i = 0; i < n; i++) {
            cin >> b[i];
        }
        for (int i = 0; i < n; i++) {
            cin >> c[i];
            --c[i];
        }
        map<int, int> mp;
        for (int i = 0; i < n; i++) {
            ++mp[b[c[i]]];
        }
        long long ans = 0;
        for (int i = 0; i < n; i++) {
            ans += mp[a[i]];
        }
        cout << ans << "
    ";
        return 0;
    }
    

    D - aab aba baa

    题意

    给出 (a, b) 的个数, 找出字典序第 (k) 小的字符串。

    题解

    首先需要计算 (i)(a)(j)(b) 可以组成多少不同的字符串,这个问题等价于从 ((0,0)) 走到 ((i,j)) 有多少种不同的走法,即 (C_{i + j}^i) ,由于会溢出 long long ,所以亦可以用动态规划解决,即 (dp_{ij} = dp_{i - 1j} + dp_{ij - 1})

    然后逐位推导即可,因为是字典序第 (k) 小的字符串,所以先考虑当前位是否可以为 (a) 。如果当前位为 (a) ,那么剩下不同字符串的个数 (dp_{i-1j}) 应该大于等于 (k) ,否则当前位为 (b) ,同时减去当前位为 (a)(dp_{i - 1 j}) 种字典序较小的情况。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int a, b;
        long long k;
        cin >> a >> b >> k;
        vector<vector<long long>> dp(a + 1, vector<long long> (b + 1));
        dp[0][0] = 1;
        for (int i = 0; i <= a; i++) {
            for (int j = 0; j <= b; j++) {
                if (i - 1 >= 0) {
                    dp[i][j] += dp[i - 1][j];
                }
                if (j - 1 >= 0) {
                    dp[i][j] += dp[i][j - 1];
                }
            }
        }
        function<string(int, int, long long)> find_kth = [&](int a, int b, long long k) {
            if (a == 0) {
                return string(b, 'b');
            }
            if (b == 0) {
                return string(a, 'a');
            }
            if (k <= dp[a - 1][b]) {
                return string("a") + find_kth(a - 1, b, k);
            } else {
                return string("b") + find_kth(a, b - 1, k - dp[a - 1][b]);
            }
        };
        cout << find_kth(a, b, k) << "
    ";
        return 0;
    }
    

    E - Count Descendants

    题意

    给出一个有 (n) 个结点的树,有 (q) 次询问,每次询问中给出整数 (u,d) ,问结点 (u) 在多少条距离根节点为 (d) 的结点的最短路中。

    题解

    从根节点出发,给每个结点打上一个访问和离开的时间戳,如下图:

    example

    如果结点 (v) 在以结点 (u) 为根节点的子树上(即结点 (v) 到根节点 (1) 的最短路经过结点 (u) ),那么显然有 (in_u le in_v < out_u) ,所以记录不同深度中每个结点的访问时间 (in_i) ,每次询问从深度为 (d) 的所有 (in_i) 中二分查找 (in_u le in_i < out_u) 的结点个数即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n;
        cin >> n;
        vector<vector<int>> G(n);
        for (int v = 1; v < n; v++) {
            int u;
            cin >> u;
            --u;
            G[u].push_back(v);
        }
        int timeStamp = 0;
        vector<int> in(n), out(n);
        vector<vector<int>> list(n);
        function<void(int, int)> dfs = [&](int u, int dep) {
            in[u] = timeStamp++;
            list[dep].push_back(in[u]);
            for (auto v : G[u]) {
                dfs(v, dep + 1);
            }
            out[u] = timeStamp++;
        };
        dfs(0, 0);
        int q;
        cin >> q;
        for (int i = 0; i < q; i++) {
            int u, d;
            cin >> u >> d;
            --u;
            cout << lower_bound(list[d].begin(), list[d].end(), out[u]) - lower_bound(list[d].begin(), list[d].end(), in[u]) << "
    ";
        }
        return 0;
    }
    

    参考资料

    https://atcoder.jp/contests/abc202/editorial

  • 相关阅读:
    SPI(1)——Documentation/spi/spi_summary.txt翻译
    TCP协议详解(TCP报文、三次握手、四次挥手、TIME_WAIT状态、滑动窗口、拥塞控制、粘包问题、状态转换图)
    Linux设备树(3)——Linux内核对设备树的处理
    Linux设备树(2)——设备树格式和使用
    [转]Android的taskAffinity
    [转]深入了解iPad上的MouseEvent
    NG2入门
    TypeScript 素描
    TypeScript 素描
    TypeScript 素描
  • 原文地址:https://www.cnblogs.com/Kanoon/p/14809659.html
Copyright © 2011-2022 走看看