题目链接。
分析:
最多有五个变量,所以枚举所有的真假值,从后向前借助于栈验证是否为永真式。

#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <stack> using namespace std; const int maxn = 10000 + 10; stack<bool> S; char s[maxn]; bool hash[200], ans; void check(char pos) { if(s[pos] == 'N') { bool x = S.top(); S.pop(); S.push(!x); } else if(s[pos] >= 'p' && s[pos] <= 't') { S.push(hash[s[pos]]); } else { bool x, y; x = S.top(); S.pop(); y = S.top(); S.pop(); if(s[pos] == 'K') S.push(x&y); else if(s[pos] == 'A') S.push(x|y); else if(s[pos] == 'C') S.push(!x | y); //即蕴含 else if(s[pos] == 'E') S.push(!(x^y)); } } int main() { //freopen("my.txt", "r", stdin); while(scanf("%s", s) == 1) { if(s[0] == '0') break; ans = true; int i; for(i=0; i<(1<<5); i++) { hash['p'] = i & 1; hash['q'] = i & (1<<1); hash['r'] = i & (1<<2); hash['s'] = i & (1<<3); hash['t'] = i & (1<<4); int pos = strlen(s)-1; while(pos >= 0) { check(pos); pos--; } ans = S.top(); S.pop(); if(ans == false) { printf("not "); break; } } if(i >= (1<<5)) printf("tautology "); } return 0; }
另一种写法
该写法参考自Disuss:http://poj.org/showmessage?message_id=168123(里面对于莫名其妙的错误还有讲解,不错)

#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <stack> using namespace std; const int maxn = 10000 + 10; char s[maxn]; int c_s, value; bool getval() { bool t1, t2; switch(s[c_s++]) { case 'p': return (value & (1<<0)); case 'q': return (value & (1<<1)); case 'r': return (value & (1<<2)); case 's': return (value & (1<<3)); case 't': return (value & (1<<4)); case 'N': return !getval(); case 'K': t1 = getval(); t2 = getval(); return t1 & t2; case 'A': t1 = getval(); t2 = getval(); return t1 | t2; case 'C': t1 = getval(); t2 = getval(); return (!t1 | t2); case 'E': t1 = getval(); t2 = getval(); return (!(t1^t2)); } } int main() { // freopen("my.txt", "r", stdin); while(scanf("%s", s) == 1) { if(s[0] == '0') break; for(value = 0; value < (1<<5); value++){ c_s = 0; if(!getval()) { printf("not "); break; } } if(value >= (1<<5)) printf("tautology "); } return 0; }