题目来源:http://poj.org/problem?id=3295
问题描述
Tautology
Description WFF 'N PROOF is a logic game played with dice. Each die has six faces representing some subset of the possible symbols K, A, N, C, E, p, q, r, s, t. A Well-formed formula (WFF) is any string of these symbols obeying the following rules:
The meaning of a WFF is defined as follows:
A tautology is a WFF that has value 1 (true) regardless of the values of its variables. For example, ApNp is a tautology because it is true regardless of the value of p. On the other hand, ApNq is not, because it has the value 0 for p=0, q=1. You must determine whether or not a WFF is a tautology. Input Input consists of several test cases. Each test case is a single line containing a WFF with no more than 100 symbols. A line containing 0 follows the last case. Output For each test case, output a line containing tautology or not as appropriate. Sample Input ApNp ApNq 0 Sample Output tautology not Source Waterloo Local Contest, 2006.9.30 |
------------------------------------------------------------
题意
给定布尔量的前缀表达式,判断表达式是否恒为1。
------------------------------------------------------------
思路
由于最多只会出现p,q,r,s,t五种变量,故暴力枚举每种变量取值0/1.
预处理部分利用set和map把p,q,r,s,t转化成布尔量枚举所有可能的情况。
计算前缀表达式用递归法。
------------------------------------------------------------
代码
#include<cstdio>
#include<cstring>
#include<set>
#include<map>
int cnt = 0; // compute函数中str的下标
char str[105];
std::set<char> pqrst;
std::map<char, bool> mapping;
bool compute() // 递归计算前缀表达式
{
bool left, right;
char ch = str[cnt++];
switch(ch)
{
case 'K':
left = compute();
right = compute();
return left && right;
break;
case 'A':
left = compute();
right = compute();
return left || right;
break;
case 'N':
left = compute();
return !left;
break;
case 'C':
left = compute();
right = compute();
return !(left && (!right));
break;
case 'E':
left = compute();
right = compute();
return left == right;
break;
default:
return mapping.at(ch);
break;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("3295.txt", "r", stdin);
#endif
int i, j, len, n;
char ch;
bool is;
std::set<char>::iterator it;
while (scanf("%s", str))
{
if (strcmp(str, "0")==0)
{
break;
}
pqrst.clear();
len = strlen(str);
is = true;
for (i=0; i<len; i++)
{
ch = str[i];
if (ch == 'p' || ch == 'q' || ch == 'r' || ch == 's' || ch == 't')
{
pqrst.insert(ch);
}
}
n = pqrst.size();
for (i=0; i<(1<<n); i++)
{
j = 0;
mapping.clear();
for (it = pqrst.begin(); it != pqrst.end(); it++)
{
mapping[*it] = ((i & (1<<j))>>j);
j++;
}
cnt = 0;
if (!compute())
{
is = false;
printf("not\n");
break;
}
}
if (is)
{
printf("tautology\n");
}
}
return 0;
}