POJ3295 Tautology(栈和枚举的应用)

Tautology

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 10073 Accepted: 3832

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

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


题目大意:

p,q,r,s,t可以取0或1,K,A,N,C,E代表某种运算符,具体题目有说明,输入给出表达式,如果这个表达式的计算结果是永真(恒为1),那么输出tautology,否则输出not.

解题思路:

永真式的定义是表达式值恒为1,所以我们只需枚举每一种情况如果都为1,那么就是永真式,否则就不是永真式。具体有两种做法,一种是利用递归,另一种则是用栈,本题个人采用的是栈来存储数据。可以把数值从右到左插入栈中,那么根据栈的优先顺序我们可以直到,先入后出,所以等价于取出值是从左往右取,满足运算顺序。


代码如下:

#include<iostream>
#include<stack>
#include<cstring>
#include<cstdio>
#include<string>
using namespace std;

stack<int> stk; //数据栈

bool judge(char ch,int pp,int qq,int rr,int ss,int tt)  //判断是运算符还是数值,如果是数值就将其压入数值栈
{
    switch(ch)
    {
        case 'p':
            stk.push(pp);
            return true;
        case 'q':
            stk.push(qq);
            return true;
        case 'r':
            stk.push(rr);
            return true;
        case 's':
            stk.push(ss);
            return true;
        case 't':
            stk.push(tt);
            return true;
    }
    return false;
}

void operator1(char ch)  //操作符
{
    switch(ch)
    {
        case 'K':
        {
            int x = stk.top();
            stk.pop();
            int y = stk.top();
            stk.pop();
            stk.push(x && y);
            break;
        }
        case 'A':
        {
            int x = stk.top();
            stk.pop();
            int y = stk.top();
            stk.pop();
            stk.push(x || y);
            break;
        }
        case 'N':
        {
            int x = stk.top();
            stk.pop();
            stk.push(!x);
            break;
        }
        case 'C':
        {
            int x = stk.top();
            stk.pop();
            int y = stk.top();
            stk.pop();
            stk.push((!x) || y);
            break;
        }
        case 'E':
        {
            int x = stk.top();
            stk.pop();
            int y = stk.top();
            stk.pop();
            stk.push(x == y);
            break;
        }
    }
}

int main()
{
    int flag;
    int p,q,r,s,t,i;
    string c;
    //freopen("111","r",stdin);
    while(cin>>c && c[0] != '0')
    {
        flag = 1;
        for(p=0; p<=1; p++)  //枚举 2^5种情况,如果都为真才是永真式
        {
            for(q=0; q<=1; q++)
            {
                for(r=0; r<=1; r++)
                {
                    for(s=0; s<=1; s++)
                    {
                        for(t=0; t<=1; t++)
                        {
                            for(i=c.size()-1; i>=0; i--) //从右往左
                            {
                                if(!judge(c[i],p,q,r,s,t)) //如果是运算符
                                {
                                    operator1(c[i]);
                                }
                            }
                            int res = stk.top();
                            stk.pop();
                            if(res == 0)
                            {
                                flag = 0;
                                break;
                            }
                        }
                        if(flag == 0)
                            break;
                    }
                    if(flag == 0)
                        break;
                }
                if(flag == 0)
                    break;
            }
            if(flag == 0)
                break;
        }
        if(flag != 0)
        {
            cout<<"tautology"<<endl;
        }
        else if(flag == 0)
        {
            cout<<"not"<<endl;
        }
        while(!stk.empty())
        {
            stk.pop();
        }
    }
    return 0;
}

运行结果:


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值