Official
A - 財布の中身 / Contents of the Wallet Editorial by admin
swe-2-high解法
問題の要求は、文字列 \(S\) の中に C(硬貨)と B(紙幣)が両方とも少なくとも \(1\) 回出現するかを判定することです。
アルゴリズム
- \(N\) と文字列 \(S\) を読み込む。
- \(S\) を走査し、
Cが出現したかを記録するフラグhasCと、Bが出現したかを記録するフラグhasBを更新する(あるいは、言語組み込みの部分文字列・文字探索機能を使う)。 hasCとhasBが両方とも真ならYesを、そうでなければNoを出力する。
正当性の証明
hasC は走査終了時点で「\(S\) の中に C が \(1\) 文字以上存在する」ことと同値になります。実際、走査では各文字を漏れなく 1 回ずつ調べ、C を見つけたときのみ hasC が真になるため、C が存在すれば真に、存在しなければ偽のままです。hasB についても同様です。
出力される答えは hasC && hasB が真のとき Yes、偽のとき No です。\(S\) は C と B のみからなるため、「硬貨と紙幣が両方とも \(1\) 枚以上入っている」という条件は「C が存在し、かつ B が存在する」と同値です。したがってこのアルゴリズムは問題の要求と正確に一致します。
\(N = 1\) の場合は \(S\) が 1 文字しか持たないので、必ず C か B のどちらか一方のみであり、正しく No が出力されます。
計算量
- 時間計算量: \(O(N)\)(各文字を 1 回ずつ調べる)
- 空間計算量: 入力文字列 \(S\) の保持に \(O(N)\)、補助的な領域はフラグのみで \(O(1)\)
なお、Python 実装では 'C' in S と 'B' in S を使っており、C++ 実装では明示的なループを使っていますが、どちらも本質的に同じ判定を行っています。