思路:
- 这类题一看就是要用栈啦,我的思路是读入 string 后从后往前操作。
- 如果遇到数字 (p、q、r、s、t) 就压栈,遇到运算符 (K、A、N、C、E) 就弹栈运算并且将子结果压栈。
- 但是我虽然想到了思路,却没敢写,因为我总觉得可以有更简单的方法判断是否恒真,但是一搜题解好像大家都是循环做的。还是要敢做,哪怕不够优呢。太没自信,这点我要检讨。
代码:
#include <iostream>
#include <stack>
#include <string>
using namespace std;
string str;
stack<bool> num;
int p,q,r,s,t;
bool CONNUM(char c){
switch (c)
{
case 'p' : return p;
case 'q' : return q;
case 'r' : return r;
case 's' : return s;
case 't' : return t;
}
}
void CONOPE(char c){
if(c == 'N'){
bool b = num.top();num.pop();
b = !b;
num.push(b);
return ;
}
bool l,r;
r = num.top();num.pop();
l = num.top();num.pop();
switch (c){
case 'K' : num.push(l && r);return ;
case 'A' : num.push(l || r);return ;
case 'C' : num.push((!l) || r);return ;
case 'E' : num.push(!(l ^ r));return ;
}
}
bool CAL(){
for(string::iterator i = str.end() - 1 ; i >= str.begin() ; i--){
if(*i <= 'z' && *i >= 'a')
num.push(CONNUM(*i));
else
CONOPE(*i);
}
if(num.top())
return true;
else
return false;
}
bool AC(){
for(p=0;p<=1;p++){
for(q=0;q<=1;q++){
for(r=0;r<=1;r++){
for(s=0;s<=1;s++){
for(t=0;t<=1;t++){
bool ans = CAL();
num.pop();
if(!ans) return false;
}
}
}
}
}
return true;
}
int main(){
while(cin>>str && str[0] != '0'){
if(AC())
cout<<"tautology"<<endl;
else
cout<<"not"<<endl;
}
return 0;
}