【AtCoder】ABC289 – A問題について解説【C++】

abc289-a プログラミング

そまちょブログのそまちょ(@somachob)です。

この記事は、Sky株式会社プログラミングコンテスト2023(AtCoder Beginner Contest 289)のA問題についての解説です。

C++の基本については、こちらの記事を参考にしてください。

競技プログラミングって何?って方はこちらの記事もぜひ見てみてください。

A – flip

■問題文

0 と 1 の 2 種類の文字からなる文字列 s が与えられます。
s に含まれる 0 を 1 に、1 を 0 に置き換えた文字列を出力してください。

■制約

  • s の長さは 1 以上 10 以下
  • s は 0 と 1 の 2 種類の文字からなる
A – flip

与えられた文字列の 0 と 1 を反転させて出力させます。

入力が 1011 だと、出力は 0100 になります。

受け取った文字列について、1文字ずつ 0 か 1 か判断して、出力する文字を分岐させます。

解答コード

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

int main () {
    // 入力
    string s;
    cin >> s;
  
    // s について1文字ずつ処理
    for (int i = 0; i < s.size(); i++){
    
        // 0 だったときは 1 を出力 
        if (s[i] == '0') cout << '1';

        // 1 だったときは 0 を出力
        if (s[i] == '1') cout << '0';
    }
    return 0;
}

入力された文字列 s の文字数は s.size() で取得することができます。

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

int main () {
    string s1 = "123";
    cout << s1.size() << endl;  // => 3
  
  	string s2 = "hello";
    cout << s2.size() << endl;  // => 5
    
    return 0;
}

文字列の左から1番目の文字にアクセスするには s[0] と書きます。

1番目の文字は 0 から始まることに注意してください。

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

int main () {
    string s = "123";
    cout << s[0] << endl;  // => 1
    cout << s[1] << endl;  // => 2
    cout << s[2] << endl;  // => 3
    return 0;
}

0 か 1 判定している if 文は、else を使って以下のように書くこともできます。

// 0 だったときは 1 を出力 
if (s[i] == '0') cout << '1';

// それ以外のときは 0 を出力
else cout << '0';

三項演算子

if 文の分岐は、三項演算子を使うことで短く書くことができます。

条件式 ? 真のとき : 偽のとき

これは以下の if 文と同じになります。

if (条件式) 真のとき
else 偽のとき
#include <bits/stdc++.h>
using namespace std;

int main () {
    // 入力
    string s;
    cin >> s;
  
    // s について1文字ずつ処理
    for (int i = 0; i < s.size(); i++){
        // 三項演算子で分岐
        cout << (s[i] == '0' ? '1' : '0');
    }
    return 0;
}

文字コード

これまでは、出力する文字は 0 か 1 によって if 文で分岐させていました。

文字コードを使って、次のように出力することもできます。

// s について1文字ずつ処理
for (int i = 0; i < s.size(); i++){

    // 出力
    cout << (char)('0' + '1' - s[i]);
}

コンピュータは、文字も数値として扱います。 (int) や (char) は、出力するときに () の中の型に変換しています。

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

int main () {
    cout << (int)'0' << endl;  // => 48
    cout << (int)'1' << endl;  // => 49
    cout << (int)'a' << endl;  // => 97
    cout << (int)'b' << endl;  // => 98
    
    cout << (char)48 << endl;  // => 0
    cout << (char)49 << endl;  // => 1
    cout << (char)97 << endl;  // => a
    cout << (char)65 << endl;  // => A

    return 0;
}

char型の 0 と 1 の文字コードはそれぞれ、48と49になります。

  • 0 の文字コード:48
  • 1 の文字コード:49

これを利用すれば 0 を 1 に、1 を 0 に置き換えることができます。それをしているのが以下のコードです。

(char)('0' + '1' - s[i])

‘0’ + ‘1’ は文字コードの足し算になります。

'0' + '1' => 48 + 49 => 97

したがって、上のコードは次と同じになります。

(char)(97 - s[i])  // '0' + '1' は 97

ここで s[i] が 0 だった場合について考えてみます。0 は文字コードで 48 です。

97 - '0' => 97 - 48 => 49

計算した結果、49 になったので、文字コード 49 に対応する文字 1 が出力されます。

// s[i] が 0 だったとして 97 - '0' => 97 - 48 => 49
(char)(49)  // 文字コード 49 に対応する 1 になる

s[i] が 1 だった場合は、(char)(48)になるので、文字コード 48 に対応する文字 0 が出力されます。

// s[i] が 1 だったとして 97 - '1' => 97 - 49 => 48
(char)(48)  // 文字コード 48 に対応する 0 になる

文字コードを利用して、以下のコードでも AC になります。

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

int main () {
    // 入力
    string s;
    cin >> s;
  
    // s について1文字ずつ処理
    for (int i = 0; i < s.size(); i++){
        // 文字コードを利用して出力
        cout << (char)('0' + '1' - s[i]);
    }
    return 0;
}

for 文

文字列を1文字ずつ処理するために for 文を使っています。

配列などのすべての要素について繰り返し処理したいときは、範囲 for 文を使うことで簡単に書くことができます。

範囲 for 文は、次のように書きます。

for (型 要素1つ分の変数名 : 処理したい変数)

次のコードでは、文字列 s を1文字ずつ char 型の変数 c に代入して処理を繰り返します。

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

int main () {
    string s = "abcdef";
  
    // s について1文字ずつ処理
    for (char c : s){
        cout << c << endl;
    }
    return 0;
}

// 出力結果
/*
a
b
c
d
e
f
*/

まとめ

for 文を使って文字列 s について1文字ずつ処理することができます。

文字列 s の文字数は、s.size() で取得できる。

文字列 s の要素にアクセスするためには、s[0] のように書く。1文字目の添え字は、0 になる。

if – else は、三項演算子を使っても書くことができる。三項演算子は、次のように書く。

条件式 ? 真のとき : 偽のとき

文字は、パソコン内では文字コードとして数値で扱われている。

配列などのすべての要素について繰り返すときは、範囲 for 文を使えば簡単に繰り返すことができる。

for (型 要素1つ分の変数名 : 処理したい変数)

競技プログラミングの勉強におすすめの書籍を紹介します。

この中でも、競技プログラミングの鉄則問題解決力を鍛える!アルゴリズムとデータ構造が特におすすめです。

タイトルとURLをコピーしました