【AtCoder】ABC 394 C - Debug | 緑コーダーが解くAtCoder
配点: 300 点 / 実行時間制限: 2 sec / メモリ制限: 1024 MB / Difficulty: 161
問題概要
英大文字のみからなる文字列 が与えられるので、
に対して、次の手順を行った後に得られる文字列を出力せよ。
- 文字列が
WAを部分文字列として含む限り、次の操作を繰り返す。- 文字列中に登場する
WAのうち最も先頭のものをACに置換する。
- 文字列中に登場する
制約
の長さは
以上
以下。
考察
基本的には、「 の先頭から1文字ずつ見ていって、直近の2文字が
WAであればACに置き換える」とすればよい。
しかし、サンプルケース2のように、 の
文字目に
Wが存在する場合、 文字目と
文字目にまたがる
WAをACに置き換えた後、連鎖的に置き換えが発生することに注意する必要がある。
ということで、stackと再帰関数を用いて実装していく。具体的なアルゴリズムは以下の通り。
- 空の
stackを用意する。 - 再帰関数
を以下のように定義する。
- もし
stackが空なら、そのままを追加して終了。
- もし
stackの先頭がWかつAならば、先頭要素をpopした後Aと
Cを実行して終了。
- それ以外のとき、そのまま
を追加して終了。
- もし
を順に実行する。
実装例
#include <bits/stdc++.h> using namespace std; #define all(x) (x).begin(), (x).end() #define rep(i, start, end) for (auto i = (start); (i) < (end); (i)++) // ======================================== // void f(stack<char> &st, char c) { if (st.empty()) { st.push(c); return; } if (st.top() == 'W' && c == 'A') { st.pop(); f(st, 'A'); f(st, 'C'); return; } st.push(c); return; } int main() { string S; cin >> S; stack<char> st; rep(i, 0, S.size()) { f(st, S[i]); } string ans = ""; while (!st.empty()) { ans += st.top(); st.pop(); } reverse(all(ans)); cout << ans << endl; return 0; }
実装時間: 10分
コメント
これとほぼ同じ要領で、 ABC351-C も解くことができる。