【競プロ日記】ABC336

 2023-11-04のABC327以来、久々に参加した。C++でプログラミングしているのだけど、久し振りにコーディングを始めたら色々と忘れている有様だ。

 さて、今回はC問題まで解くことが出来た。D問題以降は見てすらいない。C問題までの感想としては、今回は進数変換がテーマだったのかな。

コンテスト成績

 パフォーマンスは533で、レーティングは+23。とりあえず茶色に戻るまで順調に推移しても後5回くらいは掛かるかな。

A - Long Loong

 AC:2分30秒

 計算量:$O(N)$

 必要知識:繰り返し処理

 最初はstringの文字結合をしようと考えたけど、単純に標準出力に出した方が早いことに気が付いて軌道修正。

#include <iostream>
using namespace std;

int main() {
    int X = 0;

    cin >> X;
    cout << "L";

    for (int i = 0; i < X; i++) {
        cout << "o";
    }

    cout << "ng" << endl;

    return 0;
}

B - CTZ

 AC:22分30秒

 計算量:$O(\log N)$

 必要知識:繰り返し処理、2進数

 10進数を2進数に変換する方法を忘れていた。検索すればすぐに出るけど、自力で思い出したかったので時間が掛かった。公式の解説を見ると、シフト演算を利用した賢い方法をしていた。

 ああいった方法がパッと出るようになりたいものだ。その為には色々な問題を解いて知識の引き出しを増やさないと。

#include <iostream>
using namespace std;

int main() {
    int N;
    cin >> N;

    int count = 0;
    while (N % 2 == 0) {
        count++;
        N /= 2;
    }

    cout << count << endl;

    return 0;
}

C - Even Digits

 AC:1時間10分

 計算量:$O(\log N)$

 必要知識:繰り返し処理、分岐処理、進数変換

 最初の方針は、N番目の整数を表示するには何桁が必要かを求めた後、その桁の最小値から順に計算していくというものだった。

 1桁は5通り、2桁は25通り、3桁は125通りで......といった具合で考えたけど、最上位の数字は0以外でないといけない点を考慮する必要があったり、桁数が増えるにつれて計算量が膨大になりそうだったり、その方針では実装が難しそうだったからやめた。

 5進数に変換して処理すればいいじゃないか、ということに気が付いたのは最後の15分くらいで慌てて実装。細かいことを考える余裕が無かったので、とりあえず実装して入力例を試しながらデバッグ

 N=1の場合がうまくいかないけど、それはもう固定的に実装してしまえという感じでコーディング。時間ギリギリでAC。

#include <algorithm>
#include <iostream>
using namespace std;

int main() {
    long long N;
    cin >> N;

    if (N == 1) {
        cout << "0" << endl;
        return 0;
    }

    string str = "";
    N--;
    while (N != 0 ) {
        long long x = N % 5;
        if (x == 0)
            str += "0";
        else if (x == 1)
            str += "2";
        else if (x == 2)
            str += "4";
        else if (x == 3)
            str += "6";
        else if (x == 4)
            str += "8";

        N /= 5;
    }

    reverse(str.begin(), str.end());
    cout << str << endl;

    return 0;
}