POJ3295 http://poj.org/problem?id=3295
题目大意:
给定一个逻辑表达式,包含五个逻辑变量和五种运算,求问该表达式是否为重言式(永真)。
解题思路:
首先弄清楚题目给定的五种运算是什么:
K ---- w&&x
A ---- w||x
N ---- !w
C ---- (!w)||x
E ---- w==x
然后用一个栈(STL:stack),进行模拟操作。
如果是变量就压入栈,
如果是运算就分类讨论:
1.对于一元运算(就一个,N),即取出栈顶元素,取!后再将值压入栈
2.对于二元运算,(即剩下的运算符),取出两个栈顶元素,运算后将结果压入栈。
每次取栈顶元素都直接弹出栈即可。
对于五个变量,再用一个函数进行遍历,如果发现最后值为0即可直接判断不是永真式。
AC代码:
#include <iostream>
#include <cmath>
#include <stack>
#include <cstring>
using namespace std;
char a[300];
int p,q,r,s,t;
int len;
int f() {
stack<int> st;
for(int i = len - 1;i >=0 ;i--) {
if(a[i] == 'p') st.push(p);
else if(a[i] == 'q') st.push(q);
else if(a[i] == 'r') st.push(r);
else if(a[i] == 's') st.push(s);
else if(a[i] == 't') st.push(t);
else if(a[i] == 'K') {
int temp1 = st.top();st.pop();
int temp2 = st.top();st.pop();
if(temp1 == 1 && temp2 == 1) st.push(1);
else st.push(0);
}
else if(a[i] == 'A') {
int temp1 = st.top();st.pop();
int temp2 = st.top();st.pop();
if(temp1 == 0 && temp2 == 0) st.push(0);
else st.push(1);
}
else if(a[i] == 'N') {
int temp1 = st.top();st.pop();
st.push(!temp1);
}
else if(a[i] == 'C') {
int temp1 = st.top();st.pop();
int temp2 = st.top();st.pop();
if(temp1 == 1 && temp2 == 0) st.push(0);
else st.push(1);
}
else if(a[i] == 'E') {
int temp1 = st.top();st.pop();
int temp2 = st.top();st.pop();
if((temp1 == 1 && temp2 == 1) || (temp1 == 0 && temp2 == 0)) st.push(1);
else st.push(0);
}
}
return st.top();
}
int solve() {
for(p = 0;p <= 1;p++) {
for(q = 0;q <= 1;q++) {
for(r = 0;r <= 1;r++) {
for(s = 0;s <= 1;s++) {
for(t = 0;t <= 1;t++) {
int ans = f();
if(ans == 0) return 0;
}
}
}
}
}
return 1;
}
int main() {
memset(a,0,sizeof a);
while(cin >> a) {
if(a[0] == '0') return 0;
len = strlen(a);
int f = solve();
if(f) {
cout << "tautology\n";
}else {
cout <<"not\n";
}
}
return 0;
}