zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 222 复盘

    A. Four Digits

    一遍 AC。

    int n;
    
    int main() {
        scanf("%d", &n);
        std::string str = std::to_string(n);
        while (str.size() != 4) str = '0' + str;
        printf("%s
    ", str.c_str());
        return 0;
    }
    

    B. Failing Grade

    一遍 AC。

    int n, p;
    
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        cin >> n >> p;
        int ans = 0;
        rep (i, 1, n) {
            int x; cin >> x;
            ans += (x < p);
        }
        cout << ans << endl;
        return 0;
    }
    

    C. Swiss-System Tournament

    机房里吵得读不下去题,拖到后面才做的。

    WA 了 1 发,先是读错题,然后又打了好几个 typo。

    #错误警示:拒绝打错微小字符,比如 ij
    #错误警示:读好题目的数据范围信息,比如 (2n) 个人需要开两倍数组。

    const int MAXN = 50 + 10;
    const int MAXM = 100 + 10;
    
    int judge(int id1, char s1, int id2, char s2) {
        if (s1 == s2) return 2;
        if (s1 == 'G') return s2 == 'C';
        if (s1 == 'C') return s2 == 'P';
        /* s1 == 'P' */ return s2 == 'G';
    }
    
    int n, m;
    char give[MAXN * 2][MAXM];
    int rank[MAXN * 2]; // do not forget
    struct ND { int val, id; } wins[MAXN * 2];
    
    bool cmp(ND x, ND y) { return x.val == y.val ? x.id < y.id : x.val > y.val; }
    bool cmp2(ND x, ND y) { return x.id < y.id; }
    
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        cin >> n >> m;
        rep (i, 1, 2 * n) { cin >> (give[i] + 1); rank[i] = i; wins[i].id = i; }
        rep (i, 1, m) {
            // typo: i -> j
            std::sort(wins + 1, wins + 1 + 2 * n, cmp2);
            rep (j, 1, n) {
                int s1 = rank[j * 2 - 1], s2 = rank[j * 2];
                if (judge(s1, give[s1][i], s2, give[s2][i]) == 2) continue;
                if (judge(s1, give[s1][i], s2, give[s2][i])) ++wins[s1].val;
                else ++wins[s2].val;
            } std::sort(wins + 1, wins + 1 + 2 * n, cmp);
            rep (j, 1, 2 * n) rank[j] = wins[j].id;
            // rep (x, 1, 2 * n) cout << rank[x] << ' ';
            // cout << endl;
        }
        rep (i, 1, 2 * n) cout << rank[i] << endl;
        return 0;
    }
    

    D. Between Two Arrays

    f[i][j] 表示考虑前 i 个限制,第 i 次选的数是 j 的方案数。搞一个前缀和优化转移即可。

    一遍 AC。

    const int MAXN = 3000 + 10;
    const int MAXS = 3000;
    const int HA = 998244353;
    
    int n, aa[MAXN], bb[MAXN];
    int dp[MAXN][MAXN];
    lli sumdp[MAXN][MAXN]; // sum of dp[i][1~j]
    
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        cin >> n;
        rep (i, 1, n) cin >> aa[i];
        rep (i, 1, n) cin >> bb[i];
        rep (i, 1, 1) {
            rep (x, aa[i], bb[i]) dp[i][x] = 1;
            rep (x, aa[i], MAXS) (sumdp[i][x] = sumdp[i][x - 1] + dp[i][x]) %= HA;
        }
        rep (i, 2, n) {
            rep (j, aa[i], bb[i]) {
                dp[i][j] = sumdp[i - 1][j];
            } rep (j, aa[i], MAXS) (sumdp[i][j] = sumdp[i][j - 1] + dp[i][j]) %= HA;
        }
        cout << sumdp[n][bb[n]] << endl;
        return 0;
    }
    

    E. Red and Blue Tree

    首先可以算出每条边被经过的次数 (c_i),然后就可以 DP 了。

    最开始想的是 f[i][j] 表示前 (i) 条边,(R - B = j) 的方案数,但是时空复杂度是 (O(N|K|)) 的,可不可以滚动数组没试过,总觉得应该过不去就没写。

    题解又做了一步转化:设 (S = sum c_i),于是题目转化成了选择一些 (c_i) 求和得到 (frac{S + K}{2}) 的方案数((S + K < 0) 或是偶数的情况即是无解)。这就是一个背包板子了。

    时间复杂度还是 (O(N|K|)) 居然能过 离谱。

    const int MAXN = 1000 + 10;
    const int MAXM = 100000 + 10;
    const int HA = 998244353;
    
    int n, m, k;
    struct E { int v, id; };
    std::vector<E> G[MAXN];
    
    int cnt[MAXN];
    int dp[MAXM];
    
    bool dfs(int u, int fa, int end) {
        if (u == end) return true;
        bool ans = false;
        forall (G[u], i) {
            int v = G[u][i].v, id = G[u][i].id;
            if (v == fa) continue;
            if (dfs(v, u, end)) {++cnt[id]; ans = true;}
        } return ans;
    }
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        cin >> n >> m >> k;
        std::vector<int> vc;
        rep (i, 1, m) { int x; cin >> x; vc.push_back(x); }
        rep (i, 1, n - 1) {
            int u, v; cin >> u >> v;
            G[u].push_back({v, i}); G[v].push_back({u, i});
        }
        rep (i, 1, m - 1) {
            dfs(vc[i - 1], 0, vc[i]);
        }
        int S = 0;
        rep (i, 1, n - 1) {
            S += cnt[i];
        }
        if ((S + k) < 0 || ((S + k) & 1)) {
            cout << 0 << endl; return 0;
        }
        dp[0] = 1;
        for (int i = 1; i <= n - 1; ++i) {
            for (int j = MAXM - 10; j >= cnt[i]; --j) {
                (dp[j] += dp[j - cnt[i]]) %= HA;
            }
        } cout << dp[(S + k) >> 1] << endl;
        return 0;
    }
    

    F. Expensive Expense

    树的直径端点。

    后悔考场上没开这题。

    交了好几发没过,一查发现是 disdist 写 typo 了。

    #错误警示:写代码专注一点,不要纯靠肌肉记忆,因为你肌肉记忆的和这题可能有些出入。

    const int MAXN = 200000 + 10;
    int n;
    lli val[MAXN];
    
    struct E { int v; lli val; }; std::vector<E> G[MAXN];
    bool operator < (const E &x, const E &y) {
        return x.val > y.val;
    }
    
    lli dist[MAXN];
    void sp(int st, lli *dis) {
        for (int i = 1; i <= n; ++i) dis[i] = (1ll << 62); 
        std::priority_queue<E> q;
        static bool vis[MAXN]; memset(vis, 0, sizeof vis);
        q.push({st, dis[st] = 0});
        while (!q.empty()) {
            int u = q.top().v; q.pop();
            if (vis[u]) continue;
            vis[u] = true;
            forall (G[u], i) {
                int v = G[u][i].v, w = G[u][i].val;
                // typo: dist dis
                if (dis[v] > dis[u] + w) {
                    dis[v] = dis[u] + w;
                    q.push({v, dis[v]});
                }
            }
        }
    }
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        cin >> n;
        rep (i, 1, n - 1) {
            int u, v, w; cin >> u >> v >> w;
            G[u].push_back({v, w}); G[v].push_back({u, w});
        }
        rep (i, 1, n) cin >> val[i];
    
        int s1 = 0;
        sp(1, dist);
        for (int i = 1; i <= n; ++i) {
            if (dist[s1] + val[s1] < dist[i] + val[i]) {
                s1 = i;
            }
        }
        sp(s1, dist);
        int s2 = 0;
        for (int i = 1; i <= n; ++i) {
            if (s1 == i) continue;
            if (dist[s2] + val[s2] < dist[i] + val[i]) {
                s2 = i;
            }
        }
        // DEBUG(s1); DEBUG(s2);
        static lli dist2[MAXN];
        sp(s2, dist2);
        for (int i = 1; i <= n; ++i) {
            // DEBUG(dist[i]); DEBUG(dist2[i]);
            if (i == s1) cout << dist[s2] + val[s2] << endl;
            else if (i == s2) cout << dist2[s1] + val[s1] << endl;
            else {
                if (dist2[i] + val[s2] > dist[i] + val[s1]) cout << dist2[i] + val[s2] << endl;
                else cout << dist[i] + val[s1] << endl;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    ABAP 程序中的类 沧海
    ABAP类的方法(转载) 沧海
    More than 100 ABAP Interview Faq's(2) 沧海
    SAP and ABAP Memory总结 沧海
    ABAP Frequently Asked Question 沧海
    ABAP System Reports(Additional functions) 沧海
    ABAP Questions Commonly Asked 1 沧海
    ABAP Tips and Tricks 沧海
    ABAP System Fields 沧海
    ABAP 面试问题及答案(一):数据库更新及更改 SAP Standard (转) 沧海
  • 原文地址:https://www.cnblogs.com/handwer/p/15402876.html
Copyright © 2011-2022 走看看