题目大意
五个变量p,q,r,s,t
五种关系
- K and
- A or
- C ->
- E =
- N !
输入一串数,判断是否恒为真。
一开始直接开始构造树,应该是写过编译实验的缘故,没仔细想就动手了,其实一开始的两个函数一个构造一个计算结合在一起就是最后的思路。
在对输入的string逐个进行判断的同时进行计算,穷举五个变量不同取值的情况
另外这里得用bool型,下面的逻辑计算得用‘|’不能用‘||’,原因还不懂。
int cal()
{
switch(s[pos++])
{
bool a1, a2;
注意这里不能算a2,多算会导致pos的位置向前走。
case 'N': a1 = cal(); return !a1;
还需要注意的是这个算法是基于pos游标(暂且这么起名字),所以双目运算的结果得先提前算出,不然不同编译器的计算顺序不同可能会对结果造成影响。比如下面这种就可能出现问题。
case 'A': return cal() | cal();
完整代码如下。
#include <iostream>
#include <stdio.h>
#include <string>
#include <stdlib.h>
using namespace std;
string s;
int pos = 0;
int arg;
int cal()
{
switch(s[pos++])
{
bool a1, a2;
case 'p': return arg & 16;
case 'q': return arg & 8;
case 'r': return arg & 4;
case 's': return arg & 2;
case 't': return arg & 1;
case 'K': a1 = cal(); a2 = cal();return a1 & a2;
case 'A': a1 = cal(); a2 = cal();return a1 | a2;
case 'C': a1 = cal(); a2 = cal();return !a1 | a2;
case 'E': a1 = cal(); a2 = cal();return a1 == a2;
case 'N': a1 = cal(); return !a1;
default : return -1;
}
}
int main()
{
while((cin >> s) && s[0] != '0')
{
int flag = 1;
for(arg = 0; arg < 32; arg++)
{
pos = 0;
if(cal() == 0)
{
flag = 0;
break;
}
}
if(flag) printf("tautology\n");
else printf("not\n");
}
return 0;
}