AOJ 2401 恒等式
デバッグに非常に時間がかかったけどなんとか出来た。
解法
問題文中に最高のヒントが書いてあるのでそれを元に関数を作る。
<equation> ::= <formula> "=" <formula> <formula> ::= "T" | "F" | "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "-" <formula> | "(" <formula> "*" <formula> ")" | "(" <formula> "+" <formula> ")" | "(" <formula> "->" <formula> ")"
最後まで残ったバグは"a->b"のときaがtrueでbがfalseならfalseなのは良いんですがそれ以外の場合にaをtrueにする処理を書き忘れていました。
まぁデバッグの手法も学べた(consume関数)ので良し。
typedef string::const_iterator State; bool formula(State& begin, int S); bool TF(State& begin, int S); void consume(State& begin, char expected) { if (*begin == expected) { begin++; } else { cerr << "Expected '" << expected << "' but got '" << *begin << "'" << endl; cerr << "Rest string is '"; while (*begin) { cerr << *begin++; } cerr << "'" << endl; exit(1); } } bool formula(State& begin, int S) { if (*begin == '-') { begin++; return !formula(begin, S); } else if (*begin == '(') { consume(begin, '('); bool ret = formula(begin, S); if (*begin == '*') { consume(begin, '*'); ret &= formula(begin, S); consume(begin, ')'); return ret; } else if (*begin == '+') { consume(begin, '+'); ret |= formula(begin, S); consume(begin, ')'); return ret; } else { consume(begin, '-'); consume(begin, '>'); bool tmp = formula(begin, S); if (ret == true && tmp == false) ret = false; else ret = true; consume(begin, ')'); return ret; } } else { return TF(begin, S); } } bool TF(State& begin, int S) { if (*begin == 'T') { consume(begin, 'T'); return true; } if (*begin == 'F') { consume(begin, 'F'); return false; } int tmp = *begin - 'a'; begin++; return ((S>>tmp)&1) == 1; } int main() { cin.tie(0); ios::sync_with_stdio(false); while (1) { bool ng = false; string s; cin >> s; if (s == "#") break; for (int i = 0; i < 2048; i++) { State begin1 = s.begin(), begin2; for (begin2 = s.begin(); ; begin2++) { if (*begin2 == '=') { begin2++; break; } } if (formula(begin1, i) != formula(begin2, i)) { ng = true; break; } } if (ng) { cout << "NO" << endl; } else { cout << "YES" << endl; } } return 0; }