您的位置:首页 > 其它

[POJ 3295]Tautology[构造][DFS]

2016-01-12 09:59 253 查看
题目链接:[POJ 3295]Tautology[构造][DFS]
题意分析:

给出一个表达式,问:这个表达式是否是永真的?是的话,输出“tautology”,否则“not”。

其中变量最多有5个,代表字母为:p q r s t

大写字母:K-与,A-或,N-否,C-蕴含,E-相等

解题思路:

变量最多五个,那么就把所有情况都枚举一遍。解析表达式,使用dfs进行扫描,直到扫描到小写字母为止。另外要注意单目和双目运算符分类讨论下。

个人感受:

dfs的返回值社会其真值的返回值,那么dfs到达的位置信息怎么记录呢?就是说双目运算符,计算完左边的参数,那么右边的起点怎么记录呢?引用是个不错的选择!

具体代码如下:

#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<map>
using namespace std;

const int MAXN = 1e3;

bool num[5];
char op[MAXN];
map<char, int> id; // 变量值映射

int dfs(int &pos) {
char cur = op[pos];
if (islower(cur)) return num[id[cur]];

if (cur == 'N') {
++pos;
return !dfs(pos);
}
else {
++pos;
int lson = dfs(pos);
++pos;
int rson = dfs(pos);

if (cur == 'K') return (lson & rson);
else if (cur == 'A') return (lson | rson);
else if (cur == 'E') return (lson == rson);
else return !(lson == 1 && rson == 0);
}
}

int main()
{
id['p'] = 0, id['q'] = 1, id['r'] = 2, id['s'] = 3, id['t'] = 4;

while (~scanf("%s", op)) {
if (op[0] == '0') break;
bool flag = 1;
for (int i = 0; i < 1 << 5; ++i) { // 枚举所有情况
for (int j = 0; j < 5; ++j) {
num[j] = i & (1 << j);
}
int pos = 0;
if (!dfs(pos)) { // 只要一找到假的情况,就可以break了
flag = 0;
break;
}
}

if (flag) printf("tautology\n");
else printf("not\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: