POJ 3295 -- Tautology

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.
The meaning of a WFF is defined as follows:
  • 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.
Definitions of K, A, N, C, and E
     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

 

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 }

 

 

posted @ 2018-02-04 21:32  卉卉卉大爷  阅读(292)  评论(0编辑  收藏  举报