AtCoder Beginner Contest 182 Person Editorial

Problem A - twiblr

直接输出 2A+100B

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 << '\n';
    return 0;
}

Problem C - To 3

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

  • 如果本身能被 3 整除,则不需要删除。
  • 如果被 3 除余 1,则首先看是否能删去 11,然后看是否能删去 22
  • 如果被 3 除余 1,则首先看是否能删去 12,然后看是否能删去 21

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 << "\n";
    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

时间复杂度 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 << "\n";
    return 0;
}

Problem E - Akari

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

时间复杂度 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 << '\n';
    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] << '\n';
    return 0;
}

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

kiai=x

并且满足

ki,kiai∣<ai+1

的整数元组 {ki}的种数。

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

我们以{x,1}作为初始状态开始递推。看起来,状态数会以指数规模增长,但实际上,任意时刻,我们最多同时保留两个状态,因此总时间复杂度为 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];
}
posted @   RioTian  阅读(64)  评论(1编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 全程不用写代码,我用AI程序员写了一个飞机大战
历史上的今天:
2020-03-30 单源最短路径(2):Bellman Ford 算法
2020-03-30 单源最短路径(1):Dijkstra 算法
2020-03-30 【C++】fill函数,fill与memset函数的区别
点击右上角即可分享
微信分享提示

📖目录