Tautology (http://acm.pku.edu.cn/JudgeOnline/problem?id=3295)
Time Limit: 1000MS
Memory Limit: 65536K
Total Submissions: 2551
Accepted: 983
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:
- p, q, r, s, and t are WFFs
- if w is a WFF, Nw is a WFF
- if w and x are WFFs, Kwx, Awx, Cwx, and Ewx are WFFs.
- p, q, r, s, and t are logical variables that may take on the value 0 (false) or 1 (true).
- K, A, N, C, E mean and, or, not, implies, and equals as defined in the truth table below.
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
---------------------------------------------------------------------------------
Solution
Stack+Queue
import java.util.Scanner;
public class POJ_3295 {
public static boolean parse(String str, boolean p, boolean q, boolean r,
boolean s, boolean t) {
char[] stack = str.toCharArray();
int sp = stack.length - 1;
boolean[] queue = new boolean[100];
int qp = 0;
boolean a, b, c = false;
while (sp != -1) {
if (stack[sp] == 'p' || stack[sp] == 'q' || stack[sp] == 'r'
|| stack[sp] == 's' || stack[sp] == 't' || stack[sp] == 'z'
|| stack[sp] == 'x') {
switch (stack[sp--]) {
case 'p':
queue[qp++] = p;
break;
case 'q':
queue[qp++] = q;
break;
case 'r':
queue[qp++] = r;
break;
case 's':
queue[qp++] = s;
break;
case 't':
queue[qp++] = t;
break;
case 'z':
queue[qp++] = true;
break;
case 'x':
queue[qp++] = false;
break;
}
} else {
switch (stack[sp--]) {
case 'K':
a = queue[--qp];
b = queue[--qp];
c = a && b;
break;
case 'A':
a = queue[--qp];
b = queue[--qp];
c = a || b;
break;
case 'N':
a = queue[--qp];
c = !a;
break;
case 'C':
a = queue[--qp];
b = queue[--qp];
if (a == b == true)
c = true;
else if (a && !b)
c = false;
else if (!a && b)
c = true;
else
c = true;
break;
case 'E':
a = queue[--qp];
b = queue[--qp];
if (a == b)
c = true;
else
c = false;
break;
}
if (c)
stack[++sp] = 'z';
else
stack[++sp] = 'x';
}
}
return queue[0];
}
public static String preprocess(String str){
String match = "NN";
while(str.contains(match)){
int i = str.indexOf(match);
String second = str.substring(i+2);
String first = str.substring(0, i);
str = first.concat(second);
}
return str;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String input;
while (!(input = in.next()).equalsIgnoreCase("0")){
input = preprocess(input);
boolean p, q, r, s, t, result = false, pre, temp, init = false;
boolean bool[] = { true, false };
for (boolean a : bool) {
p = a;
for (boolean b : bool) {
q = b;
for (boolean c : bool) {
r = c;
for (boolean d : bool) {
s = d;
for (boolean e : bool) {
t = e;
temp = parse(input, p, q, r, s, t);
if (init == false) {
init = true;
pre = result = temp;
} else {
pre = result;
result = temp;
}
if (pre != result) {
System.out.println("not");
System.exit(0);
}
}
}
}
}
}
System.out.println("Tautology");
}
}
}