フラグ変数を 3 個持ってもいいし、set
型を使ってもいい
問題概要
文字 'A', 'B', 'C' のみからなる、長さ の文字列 が与えられます。
S を左から 1 文字ずつ見ていったときに、はじめて「A, B, C がすべて 1 回以上出現している」という条件を満たした状態になるのは、左から何文字目まで見たときですか?
制約
解法 1:3 個のフラグを用いる
次の 3 個のフラグ変数を管理する方法が簡便だと思います。
exist_A
:文字A
がここまでに出現したか (False
/True
)exist_B
:文字B
がここまでに出現したか (False
/True
)exist_C
:文字C
がここまでに出現したか (False
/True
)
for
文を用いて、文字列 の各文字に応じて、これらの負グラフ変数の値を更新していきます。3 変数すべてが True
になった瞬間に for
文を break
して抜けます。
#include <bits/stdc++.h> using namespace std; int main() { int N; string S; cin >> N >> S; // 3 個のフラグ変数 (最初はすべて false) bool exist_A = false, exist_B = false, exist_C = false; int i; // はじめて A, B, C が揃う瞬間を捉える for (i = 0; i < N; ++i) { // 文字 S[i] に応じてフラグ変数を更新 if (S[i] == 'A') exist_A = true; else if (S[i] == 'B') exist_B = true; else exist_C = true; // 3 変数すべてが true になった瞬間に for 文を抜ける if (exist_A && exist_B && exist_C) break; } // 抜けた瞬間の i を答える (i は 0 始まりなので、1 始まりにするために +1 する) cout << i+1 << endl; }
解法 2:set 型を用いる
次に、「これまでに何種類の文字が登場したか」を管理するために、集合型変数 (set
型変数) を活用する方法もあります。
具体的な方法は下コードを参考にしてみてください。set
型の変数は、すでに含まれている文字を insert
しても、重複は除外します。よって、set
型の変数のサイズ (要素数) が 3 になった瞬間に for
文を抜ければよいです。
#include <bits/stdc++.h> using namespace std; int main() { int N; string S; cin >> N >> S; // set 型変数 set<int> se; // se の要素数が 3 になる瞬間を捉える int i; for (i = 0; i < N; ++i) { se.insert(S[i]); if (se.size() == 3) break; } cout << i+1 << endl; }