接着剤の精進日記

競プロでの精進や研究に関係したことを書いていきます。

京セラプログラミングコンテスト2021(AtCoder Beginner Contest 200)

atcoder.jp

A - Century

$ \lceil \frac{N}{100} \rceil $ を出力
提出コード

void solve(){
    int N;
    cin >> N;
    cout << ceil_div(N, 100) << endl;
}

B - 200th ABC-200

問題文のとおりにシミュレートする
提出コード

void solve(){
    ll N, K;
    cin >> N >> K;
    REP(i,K){
        if(N % 200 == 0) N /= 200;
        else N = N * 1000 + 200;
    }
    cout << N << endl;
}

C - Ringo's Favorite Numbers 2

すでに見た $ A_i \pmod{200} $ の値をmapなどで管理し、今見ている $ A_j $ に対応する余りの個数を答えに加算していく
提出コード

void solve(){
    int N;
    cin >> N;
    vector<int> A(N);
    REP(i,N) cin >> A[i];
    sort(A.rbegin(), A.rend());
    map<int, int> mp;
    ll ans = 0;
    REP(i,N){
        ll rem = A[i] % 200;
        ans += mp[(rem - 200 + 200)%200];
        mp[rem]++;
    }
    cout << ans << endl;
}

D - Happy Birthday! 2

$ N \leq 8 $ のとき、数列の選び方は $ 2^8 - 1 = 255 \lt 200 $ となり、鳩ノ巣原理から答えが必ず存在する
$ N \gt 8 $ の場合、bit全探索で全探索することが出来るので、$ N = \min(N, 8) $ としてbit全探索を行えばいい
提出コード

void solve(){
    int N;
    cin >> N;
    vector<int> A(N);
    REP(i,N) cin >> A[i];

    vector<vector<int>> v(200);
    REP(i,1<<min(N, 8)){
        vector<int> t;
        int sum = 0;
        REP(j, min(N, 8)) if(i >> j & 1){
            sum = (sum + A[j]) % 200;
            t.emplace_back(j+1);
        }
        if(!v[sum].empty()){
            cout << "Yes" << endl;
            cout << v[sum].size() << " ";
            for(auto x : v[sum]) cout << x << " ";
            cout << endl;
            cout << t.size() << " ";
            for(auto x : t) cout << x << " ";
            cout << endl;
            return;
        }
        v[sum] = t;
    }
    cout << "No" << endl;
}