这段时间要沉迷刷题一段时间了,就让CSDN陪我一起吧!
一、题目大意
本题目的大体意思就是让你判断一个逻辑表达式是否为永真式,什么是永真式呢?就是说一个逻辑表达式,在各个变量取任意值的时候,结果总是真。但这里的逻辑表达式与平时的有些不同,具体的去看题目就好啦!这里不再赘述。
二、题目思路及AC代码
对于本题来说,思路其实是很简单的,就是构造嘛,而且一般对于表达式求值,都是先转化为后缀表达式,然后利用栈来求解。
当然这题也是有坑的(可能也是我的阅读理解有问题),题目中提到’Each test case is a single line containing a WFF with no more than 100 symbols’,意思是说,每一个测试用例有一行,表示一个不超过100个符号的WFF。我一开始理解的意思是变量的个数不超过100个,我一想,这不能遍历呀,2的100次方,这谁受得了!然后就想去找题解看看,结果看题解的时候看到题目大意就发现原来是理解错了,马上回去用十分钟A掉了这个题,嘿嘿,阅读理解很重要!下面给出AC代码。
#include <iostream>
#include <string>
#include <cstring>
#include <stack>
#define MAX 31 // 用于遍历所有可能
using namespace std;
bool isOp(char c) {
if (c == 'K' || c == 'A' || c == 'N' || c == 'C' || c == 'E')return true;
return false;
}
// 判断字符是否为变量
bool isVar(char c) {
if (c == 'p' || c == 'q' || c == 'r' || c == 's' || c == 't') return true;
return false;
}
// 返回当前情况下变量对应的Bool值
bool GetValue(char c, int i) {
switch (c)
{
case 'p':
return i & 1;
case 'q':
return i & 2;
case 'r':
return i & 4;
case 's':
return i & 8;
case 't':
return i & 16;
default:
break;
}
return false;
}
// 计算布尔表达式结果
bool compute(char op, bool a, bool b) {
switch (op)
{
case 'K':
return a&&b;
case 'A':
return a || b;
case 'C':
if (a && !b) return false;
else return true;
case 'E':
return !(a^b);
default:
break;
}
}
int main()
{
string expr;
while (cin >> expr) {
if (expr[0] == '0') break;
int len = expr.length();
bool flag = true;
for (int i = 0; i <= MAX; i++) {
stack<bool> s;
for (int j = len - 1; j >= 0; j--) {
char c = expr[j];
if (isVar(c)) { // 如果是变量
s.push(GetValue(c, i)); // 将对应的bool值入栈
}
if (isOp(c)) { // 如果是操作符
if (c == 'N') {
bool a = s.top(); s.pop();
s.push(!a);
}
else {
bool a = s.top(); s.pop();
bool b = s.top(); s.pop();
s.push(compute(c, b, a));
}
}
}
if (s.size() == 1 && !s.top()) {
flag = false;
break;
}
}
if (!flag) cout << "not" << endl;
else cout << "tautology" << endl;
}
return 0;
}
当然,大家也可以采用不同的方法对各种可能进行遍历,这里我采用的是按位与的方法。
如有问题,欢迎大家指正!