POJ3295 Tautology
借助的是这位大神的解题报告的写法,不愿多敲了。
大致题意:
输入由p、q、r、s、t、K、A、N、C、E共10个字母组成的逻辑表达式,
其中p、q、r、s、t的值为1(true)或0(false),即逻辑变量;
K、A、N、C、E为逻辑运算符,
K --> and: x && y
A --> or: x || y
N --> not : !x
C --> implies : (!x)||y
E --> equals : x==y
问这个逻辑表达式是否为永真式。
PS:输入格式保证是合法的。
代码操作:
1、把变量(p,q,r,s,t)替换成0,1。(替换有规律,见数组num,共32中可能);
2、用栈将字符串倒序当后缀式运算。
3、判断运算完成后栈底元素是否为1,如果不为0跳出输出not。
4、若32种可能都为1,则输出tautology;以下是代码:
#include <stdio.h> #include <string.h> int main() { char s[105],s1[105],z[105]; int top,flat,i,j,k,p; int num[32][5]= { 1,1,1,1,1, 1,1,1,1,0, 1,1,1,0,1, 1,1,1,0,0, 1,1,0,1,1, 1,1,0,1,0, 1,1,0,0,1, 1,1,0,0,0, 1,0,1,1,1, 1,0,1,1,0, 1,0,1,0,1, 1,0,1,0,0, 1,0,0,1,1, 1,0,0,1,0, 1,0,0,0,1, 1,0,0,0,0, 0,1,1,1,1, 0,1,1,1,0, 0,1,1,0,1, 0,1,1,0,0, 0,1,0,1,1, 0,1,0,1,0, 0,1,0,0,1, 0,1,0,0,0, 0,0,1,1,1, 0,0,1,1,0, 0,0,1,0,1, 0,0,1,0,0, 0,0,0,1,1, 0,0,0,1,0, 0,0,0,0,1, 0,0,0,0,0, }; while(scanf("%s",s),s[0]!='0') { flat=1; p=strlen(s); for(k=0;k<32;k++) { top=0; for(i=0;i<p;i++) { switch(s[i]) { case 'p':s1[i]=num[k][0]+'0';break; case 'q':s1[i]=num[k][1]+'0';break; case 'r':s1[i]=num[k][2]+'0';break; case 's':s1[i]=num[k][3]+'0';break; case 't':s1[i]=num[k][4]+'0';break; default:s1[i]=s[i];break; } } for(i=p-1;i>=0;i--) { if(s1[i]=='0'||s1[i]=='1') { z[top]=s1[i]; top++; } else if(s1[i]=='K') { z[top-2]=((z[top-2]-'0')&&(z[top-1]-'0'))+'0'; top--; } else if(s1[i]=='A') { z[top-2]=((z[top-2]-'0')||(z[top-1]-'0'))+'0'; top--; } else if(s1[i]=='C') { z[top-2]=((!(z[top-2]-'0'))||(z[top-1]-'0'))+'0'; top--; } else if(s1[i]=='E') { z[top-2]=((z[top-2]-'0')==(z[top-1]-'0'))+'0'; top--; } else if(s1[i]=='N') { z[top-1]=(!(z[top-1]-'0'))+'0'; } } if(z[0]=='0') { flat=0; break; } } if(flat) { printf("tautology\n"); } else { printf("not\n"); } } return 0; }