ABC 414

https://atcoder.jp/contests/abc414

A. Streamer Takahashi

https://atcoder.jp/contests/abc414/tasks/abc414_a

void solve() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int N, L, R;
    cin >> N >> L >> R;

    ll ans = 0;
    rep(i, N) {
        int x, y;
        cin >> x >> y;
        if (x <= L && R <= y) ans++;
    }
    cout << ans << endl;
}

B. String Too Long

https://atcoder.jp/contests/abc414/tasks/abc414_b

void solve() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int N;
    cin >> N;
    vector<pair<char, ll>> ps;
    ll tot = 0;
    rep(i, N) {
        char c;
        ll l;
        cin >> c >> l;
        ps.emplace_back(c, l);
        tot += l;
        if (tot > 100) {
            cout << "Too Long" << endl;
            return;
        }
    }

    for (auto [c, n] : ps) {
        rep(i, n) cout << c;
    }
    cout << endl;
}

C. Palindromic in Both Bases

https://atcoder.jp/contests/abc414/tasks/abc414_c

自力 AC. なかなか方針が立たなくてかなり時間がかかってしまった。

回文なので数字の桁数の半分が決まれば残りの桁も決まるので $1 \sim 10^6$ の数字を調べれば十分である。 十進数で回文になる数字を全探索して、その数字が $A$ 進数でも回文になるかを判定すればいい。

void solve() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    ll A, N;
    cin >> A >> N;

    auto is_palindrome_a = [&](ll s) -> bool {
        vector<ll> memo;
        while (s) {
            memo.push_back(s % A);
            s /= A;
        }

        vll rev = memo;
        reverse(all(memo));
        return memo == rev;
    };

    ll ans = 0;
    // 1桁のとき
    rep2(i, 1, 10) {
        if (is_palindrome_a(i) && i <= N) ans += i;
    }

    // 2桁以上のときの数字
    for (ll i = 1; i <= (ll)1e6; i++) {
        string s, srev;
        s = to_string(i);
        srev = s;
        reverse(all(srev));

        // 偶数長
        {
            ll cand = stoll(s + srev);
            if (cand <= N && is_palindrome_a(cand)) {
                ans += cand;
            }
        }

        // 奇数長
        rep(i, 10) {
            string x;
            x.push_back('0' + i);
            ll cand = stoll(s + x + srev);
            if (cand <= N && is_palindrome_a(cand)) {
                ans += cand;
            }
        }
    }

    cout << ans << endl;
}

D. Transmission Mission

https://atcoder.jp/contests/abc414/tasks/abc414_d

解説 AC.

考えていたこと

間違い方針

Yokan Party 的な問題かと思ったが全然違った。

異なる基地局が同じ家をカバーする意味はないので全ての基地局は別の家をカバーすると考える。 基地局によってカバーされる家の最大座標と最小座標の差がその基地局に必要な電波強度である。 全ての基地局の電波強度を $x$ で固定して $M$ 箇所の基地局でカバーできるかを二分探索して、最終的に必要な強度の総和を求めたら行けるかとおもったが全然方針違った。

正しい方針

異なる基地局が同じ家をカバーする意味はないので全ての基地局は別の家をカバーすると考える。 基地局によってカバーされる家の最大座標と最小座標の差がその基地局に必要な電波強度である。 ここまでは考えていたことと同じ。

家の位置を昇順にソートする。この位置を $M$ 個の塊に分ければよいから $N-1$ 個の家と家の隙間から $M-1$ 個を選べば $M$ 区間に分割できる。 このとき、選ぶ隙間は距離が大きい順に選ぶ、すなわち家と家の間隔が広い順に $M-1$ 個を無視することができる。 残った $N-1 - (M-1)$ 個の間隔の総和が求める値

void solve() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    ll N, M;
    cin >> N >> M;
    vll X(N);
    rep(i, N) cin >> X[i];
    sort(all(X));

    vll dists;
    rep(i, N - 1) {
        dists.push_back(X[i + 1] - X[i]);
    }

    sort(all(dists));
    rep(i, M - 1) {
        dists.pop_back();
    }

    ll ans = accumulate(all(dists), 0ll);
    cout << ans << endl;
}

E. Count A%B=C

https://atcoder.jp/contests/abc414/tasks/abc414_e

F. Jump Traveling

https://atcoder.jp/contests/abc414/tasks/abc414_f

G. AtCoder Express 4

https://atcoder.jp/contests/abc414/tasks/abc414_g