poj 3295 Tautology

8 篇文章 0 订阅

题意:
给出一个表达式,问这个表达式是否是永真式?是输出“tautology”,否则输出“not”。
其中p, q, r, s, t是变量,值为真或者假。
K, A, N, C, E分别为与、或、非、蕴含、判等操作
下面是真值表:

w xKwxAwxNwCwxEwx
1 111011
1 001000
0 101110
0 000111

分析:表达式最长不过100个字符,变量最多只有5个,枚举所有变量的状态,用栈模拟一下操作就行了。

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

const int N = 100;

void solve(char s[]) {
    static char var[26];
    static bool v[26], stk[N];
    int ls = strlen(s), index, cnt = 0, top = -1, tmp;
    memset(v, 0 , sizeof(v));
    for(int i = 0; i < ls; i++) {
        if(islower(s[i])) {
            index = s[i] - 'a';
            if(!v[index]) {
                var[cnt++] = s[i];
                v[index] = 1;
            }
        }
    }
    for(int sta = 0; sta < (1 << cnt); sta++) {
        tmp = sta;
        for(int i = 0; i < cnt; i++) {
            index = var[i] - 'a';
            v[index] = tmp & 1;
            tmp >>= 1;
        }
        for(int i = ls - 1; i >= 0; i--) {
            if(islower(s[i])) {
                index = s[i] - 'a';
                stk[++top] = v[index];
            }
            else {
                tmp = top;
                switch(s[i]) {
                    case 'K':
                        stk[--top] &= stk[tmp];
                        break;
                    case 'A':
                        stk[--top] |= stk[tmp];
                        break;
                    case 'N':
                        stk[top] = !stk[top];
                        break;
                    case 'C':
                        if(stk[top] == false) {
                            stk[--top] = true;
                        }
                        else {
                            stk[--top] &= stk[tmp];
                        }
                        break;
                    default:
                        stk[--top] = stk[tmp] == stk[tmp - 1] ? true : false;
                }
            }
        }

        if(!stk[top--]) {
            puts("not");
            return;
        }
    }
    puts("tautology");
}

int main() {
    //freopen("in.txt", "r", stdin);
    char s[N];
    while(scanf("%s", s) && s[0] != '0') {
        solve(s);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值