けんちょんの競プロ精進記録

競プロの精進記録や小ネタを書いていきます

AtCoder ABC 381 A - 11/22 String (6Q, 灰色, 150 点)

ちゃんと整理するのは大変だ。落ち着いて整理しよう。

問題概要

長さ  N の文字列  S が与えられる。 S が "11/22 文字列" であるかどうかを判定せよ。

11/22 文字列であるとは、文字 1, /, 2 がこの順に並んでいて、1 と 2 の個数が等しいものをいう。

考えたこと

0-indexed で考えることにしよう。つまり、文字列  S の先頭の文字は 0 番目であると考えることにする。

このとき、覚えておくと便利なこととして、長さ  N の文字列の真ん中の文字は


  •  N が奇数のとき:N / 2( N ã‚’ 2 で割った商)
  •  N が偶数のとき:N / 2 と N / 2 + 1

で取得できる。 N の偶奇にかかわらず、「N / 2 が真ん中だ」と覚えておくと便利だ!!! ここでは、この値を  m としておこう。

さて、そうすると次のように判定できる。

  • そもそも  N が偶数のとき:"No"
  •  i = 0, 1, \dots, m - 1 のいずれかについて S[i] != '1' のとき:"No"
  • S[m] != '/' のとき:"No"
  •  i = m + 1, m + 2, \dots, N - 1 のいずれかについて S[i] != '2' のとき:"No"

この処理は for 文を用いて実行できる。

コード

#include <bits/stdc++.h>
using namespace std;

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

    if (N % 2 == 0) {
        // そもそも文字サイズが偶数の場合はダメ
        cout << "No" << endl;
        return 0;
    }

    bool res = true;
    int mid = N / 2;  // 真ん中の文字の添字
    for (int i = 0; i < mid; i++) if (S[i] != '1') res = false;
    if (S[mid] != '/') res = false;
    for (int i = mid+1; i < N; i++) if (S[i] != '2') res = false;

    if (res) cout << "Yes" << endl;
    else cout << "No" << endl;
}