POJ 3295 -- Tautology
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 13685 | Accepted: 5276 |
Description
WFF 'N PROOF is a logic game played with dice. Each die has six faces representing some subset of the possible symbols K, A, N, C, E, p, q, r, s, t. A Well-formed formula (WFF) is any string of these symbols obeying the following rules:
- p, q, r, s, and t are WFFs
- if w is a WFF, Nw is a WFF
- if w and x are WFFs, Kwx, Awx, Cwx, and Ewx are WFFs.
- p, q, r, s, and t are logical variables that may take on the value 0 (false) or 1 (true).
- K, A, N, C, E mean and, or, not, implies, and equals as defined in the truth table below.
w x | Kwx | Awx | Nw | Cwx | Ewx |
1 1 | 1 | 1 | 0 | 1 | 1 |
1 0 | 0 | 1 | 0 | 0 | 0 |
0 1 | 0 | 1 | 1 | 1 | 0 |
0 0 | 0 | 0 | 1 | 1 | 1 |
A tautology is a WFF that has value 1 (true) regardless of the values of its variables. For example, ApNp is a tautology because it is true regardless of the value of p. On the other hand, ApNq is not, because it has the value 0 for p=0, q=1.
You must determine whether or not a WFF is a tautology.
Input
Input consists of several test cases. Each test case is a single line containing a WFF with no more than 100 symbols. A line containing 0 follows the last case.
Output
For each test case, output a line containing tautology or not as appropriate.
Sample Input
ApNp
ApNq
0
Sample Output
tautology
not
Source
大致题意:
输入由p、q、r、s、t、K、A、N、C、E共10个字母组成的逻辑表达式,
其中p、q、r、s、t的值为1(true)或0(false),即逻辑变量;
K、A、N、C、E为逻辑运算符,
K --> and: x && y
A --> or: x || y
N --> not : !x
C --> implies : (!x)||y
E --> equals : x==y
问这个逻辑表达式是否为永真式。
PS:输入格式保证是合法的。
题意分析:
首先,进行逻辑运算,需要使用栈的结构。
逻辑表达式输入的时候,现将算式存入数组WFF。
运算的时候使用栈,逻辑变量栈OPND。反向读取算式数组WFF的值,如果是操作数就进行压栈操作,如果是运算符,就进行运算,并从OPND弹出相应个数的操作数,进行运算,运算结束之后,将结果操作数压入OPND栈。重复上述操作,直到读取完算式数组WFF,这时候OPND中只剩下一个操作数,即为最后计算得到的bool值。
这里有K、A、N、C、E五个运算符,而且,N为单目运算,K、A、C、E为双目运算。
其中p、q、r、s、t的值为1(true)或0(false),将它们替换成0或1,可能的取值组合为2^5 = 32。将每一种取值可能进行逻辑运算操作,如果全为1,则为永真式tautology,如果不全为1,则为not。
这里使用十进制0~31,利用%和/运算,得到二进制串(即为opndRandom()函数),遍历p、q、r、s、t的所有取值。
1 #include<iostream> 2 #include<stack> 3 #include<stdio.h> 4 #include<cstring> 5 // 逻辑运算 6 // (注意:由于参数不是bit类型, 因此使用的是逻辑运算符而非位运算符) 7 #define _K(w, x) ((w) && (x)) // K --> and: w && x 8 #define _A(w, x) ((w) || (x)) // A --> or: w || x 9 #define _N(w) (!(w)) // N --> not : !w 10 #define _C(w, x) ((!(w)) || (x)) // C --> implies : (!w) || x 11 #define _E(w, x) ((w) == (x)) // E --> equals : w == x 12 using namespace std; 13 const int maxLen = 110; 14 stack<char> OPTR,OPND; 15 16 void opndRandom(int ran,char &p,char &q,char &r,char &s,char &t) 17 {///2^5 = 32种情况,可以用0~31的十进制数表示 18 t = ran%2;ran = ran/2; 19 s = ran%2;ran = ran/2; 20 r = ran%2;ran = ran/2; 21 q = ran%2; 22 p = ran/2; 23 } 24 bool isOperand(char c) 25 {//是操作数返回1,否则就是operator返回0 26 if(c == 'p' || c == 'q' || c == 'r' || c == 's' || c == 't') 27 return 1; 28 else return 0; 29 } 30 int main() 31 { 32 char WFF[maxLen]; 33 while(cin >> WFF && WFF[0] != '0') 34 { 35 ///计算每一种可能 36 char p,q,r,s,t; 37 int isTautology = 1; 38 for(int i=0;i<32;i++) 39 { 40 opndRandom(i,p,q,r,s,t); 41 while(!OPND.empty()) OPND.pop(); 42 while(!OPTR.empty()) OPTR.pop(); 43 ///从反向计算wwf 44 int len = strlen(WFF); 45 for(int j = len-1;j>=0;j--) 46 { 47 char w,x; 48 char c = WFF[j]; 49 if(isOperand(c)) 50 {///如果是操作数直接进栈OPND 51 if(c == 'p') c = p; 52 else if(c == 'q') c = q; 53 else if(c == 'r') c = r; 54 else if(c == 's') c = s; 55 else if(c == 't') c = t; 56 OPND.push(c); 57 }else{ 58 ///是单目运算符 59 if(c == 'N') 60 { 61 w = OPND.top(); 62 OPND.pop(); 63 c = _N(w); 64 OPND.push(_N(w)); 65 } 66 else{ 67 ///是双目运算符 68 w = OPND.top();OPND.pop(); 69 x = OPND.top();OPND.pop(); 70 if(c == 'K') 71 { 72 OPND.push(_K(w,x)); 73 }else if(c == 'A'){ 74 OPND.push(_A(w,x)); 75 }else if(c == 'C'){ 76 OPND.push(_C(w,x)); 77 }else if(c == 'E'){ 78 OPND.push(_E(w,x)); 79 } 80 } 81 } 82 } 83 ///这里需要注意,将逻辑运算的值ch压栈,实际上存入的为ascii 84 ///取出来的时候实际上取得OPND.top()的ascii值为0或者1 85 ///可以直接转为int 86 int ch = OPND.top(); 87 if(ch == 0) 88 { 89 isTautology = 0; 90 break; 91 } 92 } 93 if(isTautology == 0) cout<<"not"<<endl; 94 else cout<<"tautology"<<endl; 95 96 } 97 98 return 0; 99 }