附题目链接http://poj.org/problem?id=3295
题目大意:给定一个字符串,有特定的字符作为逻辑运算符,求给定字符串最后的计算结果。
思路:给定一个逻辑运算,逻辑运算符肯定在运算数的前面,所以最好的方法是从后往前运算。首先,在计算的时候,应该把每个字符用0 or 1随机表示出来,最多有5种运算数字符,所以把32转化成二进制数进行运算即可。用二进制数来表示随机运算数。另外,可能会出现KKwxw这类的情况,所以应该用栈把运算数存储起来,当遇到运算符时,取栈顶两个元素即可。
AC代码如下:
#include <cstdio>
#include <stack>
#include <cstring>
using namespace std;
char str[105];
int vis[205],flag,f[40][10];
void Init(int len){
for(int i = 0; i < 32; i ++){
int k = i;
for(int j = 4; j >= 0; j --){
f[i][j] = k % 2;
k /= 2;
}
}
}
void slove(){
int x,y,b;
for(int j = 0; j < 32; j ++){
stack<int> p;
for(int i = strlen(str) - 1; i >= 0; i --){
if(str[i] <= 'z' && str[i] >= 'a'){
b = f[j][str[i]-'p'];
p.push(b);
}
else{
if(str[i] == 'N'){
x = p.top(); p.pop();
x = !x;
}
else{
x = p.top(); p.pop();
y = p.top(); p.pop();
if(str[i] == 'K'){
x = x & y;
}
else if(str[i] == 'A'){
x = x | y;
}
else if(str[i] == 'C'){
if(x && !y)
x = 0;
else
x = 1;
}
else{
if(x == y)
x = 1;
else
x = 0;
}
}
p.push(x);
}
}
if(!p.top()){
flag = 0;
break;
}
}
}
/*
void display(){
for(int i = 0; i < 32; i ++){
for(int j = 0; j < 5; j ++){
printf("%d ",f[i][j]);
}
printf("\n");
}
}
*/
int main(){
Init(0);
// display();
while(~scanf("%s",str)){
if(str[0] == '0')
break;
int a[205];
memset(vis,0,sizeof(vis));
flag = 1;
slove();
if(flag)
printf("tautology\n");
else
printf("not\n");
}
return 0;
}