zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 182 Person Editorial

    Problem A - twiblr

    直接输出 (2A + 100 - B)

    Problem B - Almost GCD

    这里暴力枚举即可

    int main() {
        ios_base::sync_with_stdio(false), cin.tie(0);
        int N;
        cin >> N;
        vector<int> A(N);
        for (int i = 0; i < N; ++i) cin >> A[i];
        int Max = 0, idx = -1;
        for (int i = 2; i <= 1000; ++i) {
            int cnt = 0;
            for (int j = 0; j < N; ++j)
                if (A[j] % i == 0) cnt++;
            if (Max < cnt) Max = cnt, idx = i;
        }
        cout << idx << '
    ';
        return 0;
    }
    

    Problem C - To 3

    利用一个数能被 (3) 整除当且仅当其各位之和能被 (3) 整除。

    • 如果本身能被 (3) 整除,则不需要删除。
    • 如果被 (3) 除余 (1),则首先看是否能删去 (1)(1),然后看是否能删去 (2)(2)
    • 如果被 (3) 除余 (1),则首先看是否能删去 (1)(2),然后看是否能删去 (2)(1)

    C++ 代码

    int main() {
        ios_base::sync_with_stdio(false), cin.tie(0);
        string s;
        cin >> s;
        int cnt[3] = {0};
        for (int i = 0; i < s.length(); ++i) cnt[(s[i] - '0') % 3]++;
        int cur = (cnt[1] + 2 * cnt[2]) % 3;
        int k = cnt[0] + cnt[1] + cnt[2];
        int res;
        if (!cur) res = 0;
        else if (cur == 1) {
            if (cnt[1])
                if (k == 1) res = -1;
                else
                    res = 1;
            else {
                if (k == 2) res = -1;
                else
                    res = 2;
            }
        } else {
            if (cnt[2]) {
                if (k == 1) res = -1;
                else
                    res = 1;
            } else {
                if (k == 2) res = -1;
                else
                    res = 2;
            }
        }
        cout << res << "
    ";
        return 0;
    }
    

    Python 代码

    s = input()
    n = int(s)
    if n % 3 == 0:
        print(0)
    else:
        a = list(map(int, list(s)))
        c = [0] * 3
        for i in a:
            c[i % 3] += 1
        if c[n % 3] >= 1 and len(a) > 1:
            print(1)
        elif c[3 - n % 3] >= 2 and len(a) > 2:
            print(2)
        else:
            print(-1)
    

    Problem D - Wandering

    记录最远位置 (ans),当前位置 (pos),前缀和 (sum),以及前缀和的最大值 (hi)

    在每一轮中,首先更新前缀和,然后更新前缀和的最大值,本轮能达到的最大值显然是 (pos+hi),用其更新 (ans),再用 (pos+sum) 更新 (pos)

    时间复杂度 (mathcal{O}(N))

    using ll = long long;
    int main() {
        ios_base::sync_with_stdio(false), cin.tie(0);
        int n;
        cin >> n;
        ll a, sum = 0, hi = 0, ans = 0, pos = 0;
        for (int i = 0; i < n; ++i) {
            cin >> a;
            sum += a;
            hi = max(hi, sum);
            ans = max(ans, pos + hi);
            pos += sum;
        }
        cout << ans << "
    ";
        return 0;
    }
    

    Problem E - Akari

    将所有灯和墙都放到矩形中,然后逐行从左到右扫描一遍,再从右到左扫描一遍;逐列从上到下扫描一遍,再从下到上扫描一遍。最后统计亮着的格子即可。

    时间复杂度 (mathcal{O}(HW))

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    int e[1510][1510];
    bool vis[1510][1510];
    int cnt = 0;
    struct node {
        int x, y;
    };
    int main() {
        ios_base::sync_with_stdio(false), cin.tie(0);
        int h, w, n, m;
        cin >> h >> w >> n >> m;
        vector<node> bulbs(n);
        for (int i = 0; i < n; ++i) {
            int x, y;
            cin >> x >> y, e[x][y] = 1;  // bulb
            bulbs[i].x = x, bulbs[i].y = y;
        }
        for (int i = 0; i < m; ++i) {
            int x, y;
            cin >> x >> y, e[x][y] = 2;  // block
        }
        for (int i = 0; i < n; ++i) {
            int x = bulbs[i].x, y = bulbs[i].y;
            if (vis[x][y] == false) {
                cnt++, vis[x][y] = true;
            }
            while ((e[x][y] == 0 || (x == bulbs[i].x and y == bulbs[i].y)) &&
                   x > 0 && x <= h && y > 0 && y <= w) {
                if (vis[x][y] == false) cnt++, vis[x][y] = true;
                x++;
            }
            x = bulbs[i].x, y = bulbs[i].y;
            while ((e[x][y] == 0 || (x == bulbs[i].x and y == bulbs[i].y)) &&
                   x > 0 && x <= h && y > 0 && y <= w) {
                if (vis[x][y] == false) cnt++, vis[x][y] = true;
                x--;
            }
            x = bulbs[i].x, y = bulbs[i].y;
            while ((e[x][y] == 0 || (x == bulbs[i].x and y == bulbs[i].y)) &&
                   x > 0 && x <= h && y > 0 && y <= w) {
                if (vis[x][y] == false) cnt++, vis[x][y] = true;
                y--;
            }
            x = bulbs[i].x, y = bulbs[i].y;
            while ((e[x][y] == 0 || (x == bulbs[i].x and y == bulbs[i].y)) &&
                   x > 0 && x <= h && y > 0 && y <= w) {
                if (vis[x][y] == false) cnt++, vis[x][y] = true;
                y++;
            }
        }
        cout << cnt << '
    ';
        return 0;
    }
    

    Problem F - Valid payments

    dalao 题解,Orz...

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    const int N = 52;
    ll a[N], mx[N], xx[N], dp[N][2];
    int main() {
        ios_base::sync_with_stdio(false), cin.tie(0);
        int n;
        ll x, t;
        cin >> n >> x;
        for (int i = 1; i <= n; ++i) cin >> a[i];
        for (int i = 1; i < n; ++i) mx[i] = a[i + 1] / a[i];
        t = x;
        for (int i = n; i; --i) {
            xx[i] = t / a[i];
            t %= a[i];
        }
        dp[1][0] = 1;
        if (xx[1]) dp[1][1] = 1;
        for (int i = 1; i < n; ++i) {
            dp[i + 1][0] = dp[i][0];
            if (xx[i + 1]) dp[i + 1][1] = dp[i][0];
            dp[i + 1][1] += dp[i][1];
            if (xx[i + 1] + 1 != mx[i + 1]) dp[i + 1][0] += dp[i][1];
        }
        cout << dp[n][0] << '
    ';
        return 0;
    }
    

    这道题,我们实际上就是要求出满足

    [sum k_ia_i=x ]

    并且满足

    [∀k_i ,∣k_ia_i∣<a_{i+1} ]

    的整数元组 ({k_i})的种数。

    我们不妨从小到大进行选择。容易看到,我们其实只需要记录当前每一个可能达到的总数以及对应的方法数,而不需要记录对应的具体方案。因为(a_{i+1})总是(a_i)的倍数,所以在选择完(a_i)的系数k_iki后,我们需要保证此时的总数能够被(a_{i+1})整除。同时,因为(|k_ia_i| < a_{i+1})的限制,因此,对于每一个原有的状态,我们实际上只能有两种选择。

    我们以({x,1})作为初始状态开始递推。看起来,状态数会以指数规模增长,但实际上,任意时刻,我们最多同时保留两个状态,因此总时间复杂度为 (mathcal{O}(N))

    using ll = long long;
    int main() {
        int n;
        ll x;
        cin >> n >> x;
        vector<ll> a(n);
        for (int i = 0; i < n; ++i) cin >> a[i];
        unordered_map<ll, ll> v;
        v[x] = 1;
        ll ans = 0;
        for (int i = 0; i < n; ++i) {
            unordered_map<ll, ll> nv;
            for (auto [c, f] : v) {
                if (i + 1 < n) {
                    ll rem = c % a[i + 1];
                    nv[c - rem] += f;
                    if (rem > 0) nv[c + a[i + 1] - rem] += f;
                } else if (c % a[i] == 0)
                    nv[0] += f;
            }
            v = move(nv);
        }
        cout << v[0];
    }
    

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    【算法笔记】B1007 素数对猜想
    【算法笔记】B1006 换个格式输出整数
    【算法笔记】B1005 继续(3n+1)猜想+sort()用法
    【算法笔记】B1004 成绩排名
    【算法笔记】B1003 我要通过!
    【算法笔记】B1002 写出这个数
    【算法笔记】B1001 害死人不偿命的(3n+1)猜想
    JZOJ 3233. 照片
    JZOJ 1243. TreeCount
    JZOJ 1241. Number
  • 原文地址:https://www.cnblogs.com/RioTian/p/14599039.html
Copyright © 2011-2022 走看看