灰コーダーのABC279

永遠のBeginner / 2022-12-02T00:00:00.000Z

2022/11/26に開催された、AtCoder Beginner Contest 279へ参加しましたOsumi Akariです。最大レート340の永遠の灰コーダー( 弱いだけでは? )ですが、取り敢えずどんなことをしたのかを書いていきます。どんな考えをしてどんなコーディングをしたのかを記録してきたいと思います。

こういう記事、実はコンテスト終了後すぐに出す必要性がある気がしてならない。

A - wwwvvvvvv(00:01:45)

「v」と「w」からなる文字列が与えられて、「下に出っ張っている山の数」を答えろという問題です。急にこう言われても頭に疑問符が浮かびますが、要するにvなら1を足し、wなら2を足すという行為を行えばよいだけです。

int main(){
    string S;
    cin >> S;
    int ans = 0;
    for(int i = 0; i < S.size(); i++){
        if(S.at(i) == 'v'){
            ans++;
        }
        else{
            ans = ans + 2;
        }
    }
    cout << ans << endl;
    return 0;
}

普通にstringで文字列を受け取り、全ての文字がvかwかを判定するループを構築しました。

B - LOOKUP(00:11:14)

SとTという文字列が与えられるので、Sの中にTが存在するのかを確認するという問題です。すなわちSの部分文字列としてTが存在するのかということを確認する問題です。公式解説ではchar型の配列で文字列を受け取り、ループを回して1文字ずつチェック用として部分文字列を作り出しています。しかしながら(char型の配列ではあるものの)C++のstringにはsubstrという便利な関数が付いてくるのでこれを用いました。substrは「S.substr(何文字目から,抜き出す文字の数)」というように用いることで部分文字列を簡単に取得できるものです。SのサイズがTのサイズと等しいかそれより大きい場合にのみおいてこれを考えることで、存在するかどうかを確認することが出来ます。

int main(){
    string S,T;
    cin >> S >> T;
    bool ans = false;
    if(S.size()>=T.size()){
        for(int i = 0; i < S.size()-T.size()+1; i++){
            if(S.at(i) == T.at(0) && T == S.substr(i,T.size())){
                ans = true;
            }
        }
    }
    if(ans == true){
        cout << "Yes" << endl;
    }
    else{
        cout << "No" << endl;
    }
    return 0;
}

論理演算子を用いて真偽を判定する場合、左側がtrueになって初めて右側が評価されるという仕様になっています。この問題で計算量で引っ掛かる気はしませんでしたが、念のため(そこまででもないという意見は無きにしも非ずですが)substrという面倒な処理を毎回行わないようにするようなものにしています。

最後に

前回のAtCoder関連記事: 灰コーダーのABC256

途中でおなかが痛くなってしまったので、B問題でやる気喪失してしまいました…。当然レートは若干下がってしまいました。C問題、日本語を冷静に読み解けば両方の配列をソートして同一になるかどうかを聞いているだけと読み取れるので普通に実装できたはず。D問題は一応見るだけ見たのですが、二分探索で上手く解けないな~~(誤差がすごい)と思っていました。世の中には三分探索というものがあるらしいので、新しい情報を得られてよかったねということで。

Writer

Osumi Akari