AtCoder Beginner Contest 444

链接:https://atcoder.jp/contests/abc444

A – Repdigit

算法:

模拟。

思路:

无。

关键代码:

void miyan()
{
    int x;
    cin >> x;

    if (x % 10 == x / 10 % 10 && x % 10 == x / 100)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
}

B – Digit Sum

算法:

模拟。

思路:

无。

关键代码:

void miyan()
{
    ll n, k;
    cin >> n >> k;

    ll ans = 0;
    for (int i = 1; i <= n; ++i)
    {
        ll cnt = 0;
        ll x = i;
        while (x)
        {
            cnt += x % 10;
            x /= 10;
        }

        if (cnt == k)
            ++ans;
    }

    cout << ans << endl;
}

C – AtCoder Riko

算法:

贪心,分类讨论。

思路:

容易想到 \(L\) 只有 \(max\) 和 \(max + min\) 两种可能(\(max\) 为数组最大元素,\(min\) 为数组最小元素)。

\(max\) 证明:想要证明 \(max\) 为 \(L\) 可能的值,只需证明比 \(max\) 小的元素都不可能成为 \(L\),如果选择一个 \(x\)(小于 \(max\)),其作为 \(L\),由于 \(max > x\),其不能构成零食,因此 \(x\) 不能当作 \(L\)。

\(max + min\) 证明:想要证明 \(max + min\) 为 \(L\) 可能的值,只需证明比 \(min\) 大的元素都不可能与 \(max\) 的和构成 \(L\),如果选择一个 \(x\)(大于 \(min\)),其和 \(max\) 的和作为 \(L\),由于 \(min < x\) 且 \(min + max < x + max\),还不存在比 \(max\) 大的元素与 \(min\) 配对,因此 \(x + max\) 不能构成零食,因此 \(x + max\) 不能当作 \(L\)。

分类讨论:

  • 当 \(n\) 为奇数时,天然的多出一个元素,需要这个元素单独一对,这个单独的一对很容易想到是 \(max\),而 \(max + min\) 必然不能成为 \(L\)(证明略);
  • 当 \(n\) 为偶数时,\(maxv 和 [latex]max + min\) 都有可能。

关键代码:

void miyan()
{
    ll n;
    cin >> n;
    vector<ll> a(n);
    for (int i = 0; i < n; ++i)
        cin >> a[i];

    ranges::sort(a);

    ll maxx = a[n - 1];
    ll minn = a[0];

    if (maxx == minn)
    {
        if (n & 1)
            cout << maxx << endl;
        else
            cout << maxx << ' ' << maxx * 2 << endl;

        return;
    }

    if (n & 1)
        cout << maxx << endl;
    else
    {
        vector<int> ans;
        bool ok = 1;
        int i = 0, j = n - 1;
        for (; i <= j;)
        {
            if (i == j && a[i] + a[j] == maxx)
            {
                ok = 0;
                break;
            }

            if (a[j] == maxx)
            {
                --j;
                continue;
            }

            if (a[i] + a[j] == maxx)
                ++i, --j;
            else
            {
                ok = 0;
                break;
            }
        }

        if (ok)
            ans.push_back(maxx);

        ok = 1;
        for (int i = 0, j = n - 1; i < j;)
        {
            if (a[i] + a[j] == maxx + minn)
                ++i, --j;
            else
            {
                ok = 0;
                break;
            }
        }

        if (ok)
            ans.push_back(maxx + minn);

        for (auto x : ans)
            cout << x << ' ';
        cout << endl;
    }
}

D – Many Repunit Sum 

算法:

前缀和,差分,高精度。

思路:

板子题,不过多赘述。

关键代码:

void miyan()
{
    ll n;
    cin >> n;
    vector<ll> a(n);
    for (auto &x : a)
        cin >> x;

    vector<ll> b(N, 0);
    for (int i = 0; i < n; ++i)
    {
        b[1] += 1;
        b[a[i] + 1] -= 1;
    }

    for (int i = 1; i < N - 3; ++i)
        b[i] += b[i - 1];

    string ans;
    for (int i = 1; i < N - 3; ++i)
    {
        ll t = b[i] % 10;
        ll w = (b[i] - t) / 10;

        b[i] = t;
        b[i + 1] += w;

        ans += b[i] + '0';
    }

    while (ans.back() == '0')
        ans.pop_back();

    ranges::reverse(ans);

    cout << ans << endl;
}

E – Sparse Range

算法:

贪心,双指针,\(STL\)。

思路:

想要计算满足条件的整数对 \((L, R)\) 的数量,只需计算对于每个 \(L\) 满足条件的 \(R\) 的数量即可。

发现,当 \((L, R)\) 满足条件时,\((L, R – 1)\) 和 \((L + 1, R)\) 也满足条件,所以对于 \(L + 1\),其可以直接继承 \(L\) 的 \(R\),因此可以直接双指针。

怎样判断 \(R + 1\) 是不是可以作为 \((L, R)\) 的新结尾呢?

需要判断 \(a_R\) 是不是与 \((L, R)\) 中的每个 \(i\) 都满足 \(|a_i – a_R| \ge D\),判断这个不等式是否对于每个 \(i\) 都成立,可以直接判断与 \(a_R\) 的值最相近的 \(a_i\),既小于 \(a_R\) 的第一个 \(a_i\) 和大于 \(a_R\) 的第一个 \(a_i\) 是否满足不等式,判断时可以使用 \(set\) 维护当前区间集合,在 \(O(logn)\) 是时间内找到这两个元素。

关键代码:

void miyan()
{
    ll n, d;
    cin >> n >> d;
    vector<ll> a(n);
    for (auto &x : a)
        cin >> x;

    set<int> S;
    auto check = [&](ll x) -> bool
    {
        auto it = S.lower_bound(x);
        if (it != S.end() && *it - x < d)
            return 0;

        it = S.upper_bound(x);
        if (it != S.begin() && x - *prev(it) < d)
            return 0;

        return 1;
    };

    ll ans = 0;
    for (int i = 0, j = 0; i < n; ++i)
    {
        while (j < n && (S.empty() || check(a[j])))
            S.insert(a[j++]);

        ans += j - i;

        S.erase(a[i]);
    }

    cout << ans << endl;
}

F – Half and Median

还没补。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇