3295
题目描述
题目简介:
重言表达式求解是否为永真式
方法:
栈,前缀不等式
解题思路:
详见代码
完整代码:
#include "iostream"
#include "string"
#include "map"
#include "stack"
#define Max_Length 101 //表达式最大长度
#define NUM 10 //变量数量
typedef long long ll;
using namespace std;
int status[NUM]; //记录每个变量的取值
map<char, int>Map;
int vis[5][5][5];
string s;
void init(){ //预处理操作,用枚举法枚举出每一个对变量操作之后得到的0-1值表
Map['K'] = 0;
Map['A'] = 1;
Map['C'] = 2;
Map['E'] = 3;
//K w x
vis[0][1][1] = 1;
vis[0][1][0] = 0;
vis[0][0][1] = 0;
vis[0][0][0] = 0;
//A w x
vis[1][1][1] = 1;
vis[1][1][0] = 1;
vis[1][0][1] = 1;
vis[1][0][0] = 0;
//C w x
vis[2][1][1] = 1;
vis[2][1][0] = 0;
vis[2][0][1] = 1;
vis[2][0][0] = 1;
//E w x
vis[3][1][1] = 1;
vis[3][1][0] = 0;
vis[3][0][1] = 0;
vis[3][0][0] = 1;
}
int solve(){ // 求解对于变量确定取值的表达式
stack<bool>Stack;
for(int i = s.size()-1; i >= 0; i--){
if(islower(s[i])) Stack.push(status[s[i]-'p']); //如果是小写则将对应变量取值压栈
else{ //对于大写操作,'N'是对某一个变量的, 其他的操作都是对应两个变量,故分类
if(s[i] =='N'){
bool w = Stack.top();
Stack.pop();
w = !w;
Stack.push(w);
}
else{
bool w = Stack.top();
Stack.pop();
bool x = Stack.top();
Stack.pop();
bool result = vis[Map[s[i]]][w][x];
Stack.push(result);
}
}
}
return Stack.top();
}
int main(){
init();
while (getline(cin, s)){
if(s.size()==1 && s[0] == '0') break;
else {
int flag = 1; //标志是不是tautology式
for(int i = 0; i < (1<<5);i++){ //考虑五个变量的所有取值情况,此处将五个变量变成了五位二进制数,用status数组进行记录,通过按位与的操作取到每一种情况,
for(int j = 0; j < 5;j++){
if(i & (1<<j)) status[j] = 1;
else status[j] = 0;
}
if(!solve()){
flag = 0; break;
}
}
if(flag == 1) cout << "tautology" << endl;
else cout << "not" << endl;
}
}
return 0;
}