题意分析:
文字版:
给你一个逻辑表达式,pqrst等小写字母代表原子(就是有逻辑值0或者1的变量),AKNEC等分别代表了或,与,非,相等,蕴含关系。问无论原子值为何,表达式为恒真吗?
解题思路:
KNppANpq,分析这个样例你会发现其实只要根据规则进行类似后缀表达式求值的过程即可,这不过这里需要逆向思维。这个题不需要考裂不合法的表达式!
测试样例:
- 输入:
KNppANpq
KNppANpp
0
- 输出:
not
not
解题代码:
#include<iostream>
#include<cmath>
#include<string>
#include<stack>
using namespace std;
int main()
{
string str;
int f[33][6];
for (int i = 0; i < 32; i++)
{
f[i + 1][5] = i % 2;
f[i + 1][4] = i / 2 % 2;
f[i + 1][3] = i / 4 % 2;
f[i + 1][2] = i / 8 % 2;
f[i + 1][1] = i / 16 % 2;
}
while (cin >> str && str[0] != '0')
{
int ans = 0;
cout << str;
for (int i = 1; i < 33; i++)
{
stack<int>s1;
stack<char>s2;
for (int j = str.size() - 1; j >= 0; j--)
{
if (str[j] >= 'p' && str[j] <= 't')
{
s1.push(f[i][str[j] - 'o']);
}
else {
int num1, num2 = 0;
char op = str[j];
cout << int(str[j]) << "=" << int(op);
if (op == 'K')
{
num1 = s1.top();
s1.pop();
num2 = s1.top();
s1.pop();
s1.push(num1 && num2);
}
else if (op == 'A')
{
num1 = s1.top();
s1.pop();
num2 = s1.top();
s1.pop();
s1.push(num1 || num2);
}
else if (op == 'C')
{
num1 = s1.top();
s1.pop();
num2 = s1.top();
s1.pop();
s1.push((!num1) || num2);
}
else if (op == 'E')
{
num1 = s1.top();
s1.pop();
num2 = s1.top();
s1.pop();
s1.push(num1 == num2);
}
else if (op == 'N')
{
num1 = s1.top();
s1.pop();
s1.push(!num1);
}
}
}
ans = s1.top();
if (ans == 0)
{
cout << "not" << endl;
break;
}
}
if (ans == 1)
{
cout << "tautology\n";
}
}
return 0;
}