POJ 3295 - Tautology
http://poj.org/problem?id=3295
概要
変数 p, q, r, s, t を含む論理式が与えられ,それがトートロジーかどうか答える.
制約
- 式は100文字以下
解法
変数が最大でも5種類しかないので,全通り試してすべて真になったらトートロジーと判定する. パースも簡単.
poj/3295.cc1 #include <iostream> 2 #include <vector> 3 #include <cctype> 4 #include <cassert> 5 using namespace std; 6 7 struct formula 8 { 9 char var; 10 char op; 11 const formula *lhs, *rhs; 12 formula(char v) : var(v), op(0), lhs(0), rhs(0) {} 13 formula(char o, const formula *l, const formula *r = 0) 14 : var(0), op(o), lhs(l), rhs(r) {} 15 ~formula() { delete lhs; delete rhs; } 16 bool eval(bool bs[5]) const 17 { 18 if (var) { 19 return bs[var-'p']; 20 } else { 21 switch (op) { 22 case 'K': return lhs->eval(bs) && rhs->eval(bs); 23 case 'A': return lhs->eval(bs) || rhs->eval(bs); 24 case 'N': return !lhs->eval(bs); 25 case 'C': return !lhs->eval(bs) || rhs->eval(bs); 26 case 'E': return lhs->eval(bs) == rhs->eval(bs); 27 default: throw "unknown operator"; 28 } 29 } 30 } 31 }; 32 33 typedef string::const_iterator Iterator; 34 const formula *parse(Iterator& it, const Iterator& last) 35 { 36 assert(it != last); 37 if (islower(*it)) { 38 const char v = *it; 39 ++it; 40 return new formula(v); 41 } else if (*it == 'N') { 42 ++it; 43 return new formula('N', parse(it, last)); 44 } else { 45 const char op = *it; 46 ++it; 47 const formula *l = parse(it, last); 48 const formula *r = parse(it, last); 49 return new formula(op, l, r); 50 } 51 } 52 53 bool tautology(const formula *f) 54 { 55 for (int s = 0; s < (1<<5); s++) { 56 bool bs[5]; 57 for (int i = 0; i < 5; i++) { 58 bs[i] = (s & (1<<i)) != 0; 59 } 60 if (!f->eval(bs)) { 61 return false; 62 } 63 } 64 return true; 65 } 66 67 int main() 68 { 69 string s; 70 while (cin >> s && s != "0") { 71 Iterator it = s.begin(); 72 const Iterator last = s.end(); 73 const formula *f = parse(it, last); 74 cout << (tautology(f) ? "tautology" : "not") << endl; 75 delete f; 76 } 77 }