wrong了好多次。。我才发现我把E没注意 以为是异或,其实是判断是否相等。。。。orz
这题应该不能算是自己独立思考出来的,之前有思考过但是因为我是从正序想的所以导致没有什么头绪,,看了下解题报告的思路,说要用stack,刚好小紫书正要学,就先放下了,小紫书学了后,来做这题。当然我是直接用STL里面的orz。。
思路主要就是要利用题目的特性,从后往前读字符串是最直观的,然后对于pqrst来说要枚举每一种情况,用五个循环就行啦。。然后可以使用一个map来进行pqrst与各自对应值的映射。。还有就是利用stack啦,从后往前读并其入栈,然后出栈和运算符进行运算再将运算的结果入栈,像not就只要将一个出栈,而其他的需要将两个元素出栈来进行一系列的运算。。这样一直做到最后一定就会只剩一个在栈内,取出来其值就是整个表达式的值。。。还有就是每组数据结束之后要记得将那个值出栈避免留栈内,否则最后会有很多组的数都留在了栈内。。。万一测试数据超级多可能爆掉。。(虽然我忘了出栈也AC了但是还是规范点好)
附上ac代码:
#include<cstdio>
#include<cstring>
#include<stack>
#include<map>
using namespace std;
char s[150];
map<char,int> ID;
stack<int> WFF;
int scan()
{
for(int i = strlen(s)-1;i >= 0;i--)
{
if(s[i]>='p'&&s[i]<='t')
WFF.push(ID[s[i]]);
else if(s[i] == 'N')
{
int x = WFF.top();
WFF.pop();
WFF.push(!x);
}
else if(s[i] == 'K')
{
int x1 = WFF.top();
WFF.pop();
int x2 = WFF.top();
WFF.pop();
WFF.push(x1&&x2);
}
else if(s[i] == 'A')
{
int x1 = WFF.top();
WFF.pop();
int x2 = WFF.top();
WFF.pop();
WFF.push(x1||x2);
}
else if(s[i] == 'C')
{
int x1 = WFF.top();
WFF.pop();
int x2 = WFF.top();
WFF.pop();
WFF.push((!x1)||x2);
}
else if(s[i] == 'E')
{
int x1 = WFF.top();
WFF.pop();
int x2 = WFF.top();
WFF.pop();
WFF.push(x1==x2);
}
}
return WFF.top();
}
int main ()
{
while(scanf("%s",s)==1)
{
if(s[0]=='0') break;
int flag=0;
for(ID['p'] = 0;ID['p'] < 2;ID['p']++)
for(ID['q'] = 0;ID['q'] < 2;ID['q']++)
for(ID['r'] = 0;ID['r'] < 2;ID['r']++)
for(ID['s'] = 0;ID['s'] < 2;ID['s']++)
for(ID['t'] = 0;ID['t'] < 2;ID['t']++)
{
if(!scan())
{
flag=1;
goto out;
}
}
out:
if(flag) printf("not\n");
else printf("tautology\n");
WFF.pop(); //要将栈内的元素弹出来,不要让它留在栈里
}
return 0;
}