michihiko-yamamoto Blog

AtCoder abc397 振り返り

Cover Image for AtCoder abc397 振り返り

AtCoder Beginner Contest 397 の振り返りです。

AtCoder Beginner Contest 397

ABC397の振り返りです。 今週はB問題以降がすこし難しいっぽい配点だったので、解けるか不安でしたが無事に3問解けた感じでした。 D問題以降は全くわからなかった。

ABC397

コンテスト成績 >

A Thermometer: Solved

与えられる体温に応じて、高温/微熱/平熱かどうかを判定する問題。

単純にif文で条件分岐していくだけの問題。

B Ticket Gate Log: Solved(1ペナ)

iとoが連続する文字列が与えられ、iが奇数番目、oが偶数番目になるようにするには何回の補完が必要かを答える問題。

iiとooの出現回数を数えて、両端がiで始まりoで終わっているかに応じて回数を加算することでACできたが、1回目の提出で末端処理をミスったため1ペナくらってしまった。

int main() {
    string s;
    cin >> s;
    int c = 0;
 
    if(s[0] == 'o'){
        c++;
    }
    for(int i=1;i < s.size(); i++){
        if(s[i] == 'i' && s[i-1] == 'i'){
            c++;
        }
        if(s[i] == 'o' && s[i-1] == 'o'){
            c++;
        }
    }
    if(s[s.size() -1]=='i'){
        c++;
    }
    cout << c << endl;
}

C Variety Split Easy: Solved

与えられた数列において、二つの部分に分割し、それぞれに含まれる数字の種類の合計が最大になるときの値を答える問題。

前方から文字の種数を数えて配列に格納していき、後方からも同様に配列に格納した。文字の種数はSetを使って数えたけれど、解答を見るとvector<int>で出現回数を数えていた。 この問題だったらどっちでもいいんだろうけど、F問題がこの問題の難しいバージョンで、そちらはSetだと解けなさそうだったので、vector<int>で数える方が良いのかもしれない。

とはいえ、この問題をストレートにACできたのはよかった。

int main() {
    int n;
    cin >> n;
    vector<int> a(n),l(n),rl(n);
    for(int i=0;i<n;i++){
        cin >> a[i];
    }
    set<int> s,rs;
    for(int i=0;i<n;i++){
        s.insert(a[i]);
        l[i] = s.size();
        rs.insert(a[n - i - 1]);
        rl[n-i-1] = rs.size();
    }
    long long mx = 0;
    for(int i=1;i<n;i++){
        mx = max(mx, l[i-1] + rl[i]);
    }
    cout << mx << endl;
}

所感

C問題がいつもよりちょっと難しい350点配点だったので、どんな問題が来るかと心配していたが、蓋を開けてみるとストレートでACできたのでよかった。 ただ、その分B問題で1ペナくらってしまったのが痛かった。

D問題以降にも挑んだが、D問題が整数問題で全く歯が立たず、数式変形して探索範囲を限定していくという発想に至らず、立方数の性質をひたすら勉強している時間だった。(それはそれで楽しかった。)

なかなかD問題の壁が高いけれど、350点問題は解けているので、あとちょっとでD問題が解けるようになると信じたい。