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;
}