POJ3295 Tautology

题意

描述

通过一个合法逻辑表达式将5个布尔变量进行逻辑运算,检验改逻辑表达式是不是重言式。这个表达式会有K, A, N, C, E, p, q, r, s, t 10种字符,5个小写字符代表变量,五个大写字符分别代表and, or, not, implies, equals。并且存在规则:

  • p、q、r、s 、t 是逻辑变量,它们的值可能为 0(假)或 1(真),它们都是 合法逻辑表达式
  • 如果 w 是 合法逻辑表达式,则 Nw 是 合法逻辑表达式
  • 如果 w 和 x 是 合法逻辑表达式,则 Kwx、Awx、Cwx 和 Ewx 是 合法逻辑表达式。
    真值表

输入

输入由几个测试用例组成。每个测试用例一行,其中包含一个不超过 100 个符号的合法逻辑表达式。全部样例输入完成后以0结尾。

输出

对于每个测试用例,输出一行是否包含重言式。

Sample Input

ApNp
ApNq
0

Sample Output

tautology
not

思路

这道题属于构造法,首先分析怎么解析这个字符串:
典型的前缀表达式,直接用前缀表达式的思路莽就完事了。而且输入样例全部是合法表达式,不用判断会不会出现奇怪的输入,就很舒服。
至于怎么判断是不是重言式,5种变量,每个都有真假两种情况,32种情况,往里带就完事了。

题解代码

不用怀疑,10个case解决战斗。

#include <stdio.h>
#include <stack>

using namespace std;
stack<char> formula;

bool list[32][5] = {
{0,0,0,0,0},
{0,0,0,0,1},
{0,0,0,1,0},
{0,0,0,1,1},
{0,0,1,0,0},
{0,0,1,0,1},
{0,0,1,1,0},
{0,0,1,1,1},
{0,1,0,0,0},
{0,1,0,0,1},
{0,1,0,1,0},
{0,1,0,1,1},
{0,1,1,0,0},
{0,1,1,0,1},
{0,1,1,1,0},
{0,1,1,1,1},
{1,0,0,0,0},
{1,0,0,0,1},
{1,0,0,1,0},
{1,0,0,1,1},
{1,0,1,0,0},
{1,0,1,0,1},
{1,0,1,1,0},
{1,0,1,1,1},
{1,1,0,0,0},
{1,1,0,0,1},
{1,1,0,1,0},
{1,1,0,1,1},
{1,1,1,0,0},
{1,1,1,0,1},
{1,1,1,1,0},
{1,1,1,1,1}};

bool lnow[5];
int lenth;
char fnow[105];

bool findb(char c){
  switch (c){
    case 'p':
      return lnow[0];
    case 'q':
      return lnow[1];
    case 'r':
      return lnow[2];
    case 's':
      return lnow[3];
    case 't':
      return lnow[4];
    default:
      return false;
  }
}

int checkans(){
  bool tmp1,tmp2;
  for(int i = lenth-1 ; i >= 0 ; i--){
    switch (fnow[i]){
      case 'p':
        {
          formula.push(lnow[0]); 
          break;
        }
      case 'q':
        {
          formula.push(lnow[1]);
          break;
        }
      case 'r':
        {
          formula.push(lnow[2]);
          break;
        }
      case 's':
        {
          formula.push(lnow[3]);
          break;
        }
      case 't':
        {
          formula.push(lnow[4]);
          break;
        }
      case 'N':
        {
          tmp1 = formula.top();
          formula.pop();
          formula.push(!tmp1);
          break;
        }
      case 'K':
        {
          tmp1 = formula.top();
          formula.pop();
          tmp2 = formula.top();
          formula.pop();
          formula.push(tmp1 && tmp2);
          break;
        }
      case 'A':
        {
          tmp1 = formula.top();
          formula.pop();
          tmp2 = formula.top();
          formula.pop();
          formula.push(tmp1 || tmp2);
          break;
        }
      case 'C':
        {
          tmp1 = formula.top();
          formula.pop();
          tmp2 = formula.top();
          formula.pop();
          formula.push(!tmp1 || tmp2);
          break;
        }
      case 'E':
        {
          tmp1 = formula.top();
          formula.pop();
          tmp2 = formula.top();
          formula.pop();
          formula.push(tmp1 == tmp2);
          break;
        }
      default :
        break;
    }
  }
  tmp1 = formula.top();
  formula.pop();
  return tmp1;
}




int main(){
  while(1){
    char c;
    for(int i = 0 ; i < 105 ; i++){
      scanf("%c",&c);
      if(c == '0') return 0;
      if(c == '\n'){
        lenth = i;
        break;
      } else{
        fnow[i] = c;
      }
    }
    int ans = 0;
    for(int i = 0 ; i < 32 ; i++){
      for(int j = 0 ; j < 5 ; j++)
        lnow[j] = list[i][j];
      ans += checkans();
    }
    if(ans  == 32)
      printf("tautology\n");
    else
      printf("not\n");
  }
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值