Balanced Smileys
問題
:) やら :( やらが含まれる文字列で、カッコの対応が付いているかチェックせよ。
考え方
- 考慮すべきカッコに種類があるわけではない。
- Smiley が関係無い場合、カッコを潜っている段数 n を見るだけでいいテンプレ問題が有るのを思い出す。
- 途中は n>=0 をキープし、最後に n==0 となれば OK
- カッコの前に : があったら Smiley になる可能性があるから分岐させればいい。
- こんなときは DP すると良さ気。
- 最初のカッコの時だけ : チェックしない例外とか面倒だからスペース入れておこ…
コード
#include <algorithm> #include <cstdlib> #include <iostream> #include <set> #include <string> using namespace std; bool Solve() { string line; getline(cin, line); line = ' ' + line; set<int> a, b; set<int>* st = &a, * st2 = &b; st->insert(0); for (int i = 0; i < line.size(); ++i) { if (line[i] != '(' && line[i] != ')') continue; st2->clear(); set<int>::iterator itr; if (line[i] == '(') { for (itr = st->begin(); itr != st->end(); ++itr) st2->insert(*itr + 1); if (line[i - 1] == ':') for (itr = st->begin(); itr != st->end(); ++itr) st2->insert(*itr); } else if (line[i] == ')') { for (itr = st->begin(); itr != st->end(); ++itr) if (*itr > 0) st2->insert((*itr) - 1); if (line[i - 1] == ':') for (itr = st->begin(); itr != st->end(); ++itr) st2->insert(*itr); } swap(st, st2); } return (st->find(0) != st->end()); } int main(void) { string line; getline(cin, line); const int n = atoi(line.c_str()); for (int i = 0; i < n; ++i) { cout << "Case #" << (i + 1) << ": " << (Solve() ? "YES\n" : "NO\n"); } return 0; }