ABC 424

https://atcoder.jp/contests/abc424

A. Isosceles

https://atcoder.jp/contests/abc424/tasks/abc424_a

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

    vint v(3);
    rep(i, 3) cin >> v[i];
    sort(all(v));

    yesno(v[0] == v[1] || v[1] == v[2]);
}

B. Perfect

https://atcoder.jp/contests/abc424/tasks/abc424_b

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

    ll N, M, K;
    cin >> N >> M >> K;
    vint A(K), B(K);
    rep(i, K) {
        cin >> A[i] >> B[i];
        A[i]--, B[i]--;
    }

    vvint sol(N, vint(M));
    vint ans;
    rep(i, K) {
        sol[A[i]][B[i]] = 1;

        int cnt = 0;
        rep(j, M) if (sol[A[i]][j]) cnt++;
        if (cnt == M) ans.push_back(A[i] + 1);
    }

    print(ans);
}

C. New Skill Acquired

https://atcoder.jp/contests/abc424/tasks/abc424_c

自力 AC. コンテスト後にグラフに落とし込めるとわかったが、コンテスト中は stack 使って実質再帰の処理を書いた。

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

    ll N;
    cin >> N;

    vint start;
    vvint graph(N + 1);
    rep(i, N) {
        ll a, b;
        cin >> a >> b;
        if (a == 0 && b == 0) {
            graph[0].push_back(i + 1);
        } else {
            graph[a].push_back(i + 1);
            graph[b].push_back(i + 1);
        }
    }

    vint visited(N + 1);
    auto dfs = [&](auto dfs, int x) -> void {
        for (auto nx : graph[x]) {
            if (visited[nx]) continue;
            visited[nx] = 1;
            dfs(dfs, nx);
        }
    };

    dfs(dfs, 0);

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

D. 2x2 Erasing 2

https://atcoder.jp/contests/abc424/tasks/abc424_d

解説 AC.

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

    int M = 7;

    // 連続する行の中に 2x2 の黒いマスが存在しないか判定
    auto judge = [&](int a, int b) -> bool {
        int t = a & b;
        rep(i, M - 1) {
            if (t >> i & 1 && t >> (i + 1) & 1) return false;
        }
        return true;
    };

    auto cal = [&]() -> void {
        ll H, W;
        cin >> H >> W;
        vector<string> tmpgrid(H);
        rep(i, H) cin >> tmpgrid[i];

        vint grid(M + 1);
        rep(i, H) rep(j, W) {
            if (tmpgrid[i][j] == '#') {
                grid[i + 1] ^= 1 << j;
            }
        }

        // sentinel として 0 行目を全て白いマスとして追加
        // dp[i][state] := i 行目まで見たときに i 行目の状態が state で、また 0 ~ i 行目までに2x2の黒マスが存在しないように白マスで塗りつぶすときの最小値
        vvll dp(M + 1, vll(1 << M, INF));
        dp[0][0] = 0;
        rep2(i, 1, M + 1) rep(pr, 1 << M) rep(nx, 1 << M) {
            if (!judge(pr, nx)) continue;

            // i 行目を nx の状態にできるか判定
            // できるのであれば何個のマスを白マスにする必要があるか数える
            ll cnt = 0;
            int row = grid[i];
            int ok = 1;
            rep(j, M) {
                int l = (row >> j & 1);
                int r = (nx >> j & 1);
                if (l == 0 && r == 1) {
                    ok = 0;
                    break;
                }
                if (l == 1 && r == 0) cnt++;
            }
            if (!ok) cnt = INF;
            chmin(dp[i][nx], dp[i - 1][pr] + cnt);
        }

        ll ans = INF;
        rep(st, 1 << M) chmin(ans, dp[M][st]);
        cout << ans << '\n';
    };

    int t;
    cin >> t;
    rep(i, t) cal();
}

E. Cut in Half

https://atcoder.jp/contests/abc424/tasks/abc424_e

F. Adding Chords

https://atcoder.jp/contests/abc424/tasks/abc424_f

G. Set list

https://atcoder.jp/contests/abc424/tasks/abc424_g