题目1 : Logic Expression Tree
hiho一下 第217周
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
You are given a logic expression tree of N nodes which are numbers from 1 to N. The leaf nodes are boolean values(TRUE, FALSE) and the non-leaf nodes are logic operators(AND, OR). The value of tree is the boolean value when you calculate the expression from leaves to the root. For example below is a logic expresssion tree whose valus is TRUE AND (FALSE OR TRUE) = TRUE.
AND
/ \
T OR
/ \
F T
Now you want to reverse the value of the tree (from TRUE to FALSE or vice versa). You want to know how many operators at least are needed to be reversed (from AND to OR or vice versa). For example you only need to reverse the OR operator into AND to make the tree from TRUE to FLASE.
输入
The first line contains an integer N. (1 <= N <= 100)
The i-th line of the following N lines contains an integer Pi and a string Si.
Pi denotes the number of the i-th node's parent node. Pi = 0 indicates that the i-th node is the root. (0 <= Pi <= N)
Si is either TRUE, FALSE, AND or OR denoting the boolean value or logic operator of the node.
输出
The minimum number of operators needed to be reversed. If you cannot reverse the value no matter how many operators are reversed output -1.
样例输入
5
0 AND
1 TRUE
1 OR
3 FALSE
3 TRUE
样例输出
1
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static class Tree {
List<Tree> children;
int parentIndex;
boolean isLeaf;
boolean value;
int operator; // 0 for or, 1 for and
}
public static void main(String[] args) throws IOException {
List<Tree> trees = new ArrayList<>();
init(trees);
System.out.println(calculate(trees.get(0)));
}
public static void init(List<Tree> trees) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
for (int i = 0; i < n; i++) {
String[] ss = br.readLine().split(" ");
int p = Integer.parseInt(ss[0]);
Tree tree = new Tree();
tree.children = new ArrayList<>();
switch (ss[1]) {
case "TRUE":
tree.isLeaf = true;
tree.value = true;
break;
case "FALSE":
tree.isLeaf = true;
tree.value = false;
break;
case "AND":
tree.isLeaf = false;
tree.operator = 1;
break;
case "OR":
tree.isLeaf = false;
tree.operator = 0;
break;
}
if (p != 0) {
tree.parentIndex = p - 1;
trees.get(p-1).children.add(tree);
}
trees.add(tree);
}
for (int i = n - 1; i >= 0; i--) {
Tree t = trees.get(i);
if (!t.isLeaf) {
if (t.operator == 0) {
t.value = t.children.get(0).value || t.children.get(1).value;
} else {
t.value = t.children.get(0).value && t.children.get(1).value;
}
}
}
}
public static int calculate(Tree tree) {
if (tree.isLeaf)
return -1;
boolean value0 = tree.children.get(0).value;
boolean value1 = tree.children.get(1).value;
if (value0 != value1)
return 1;
int min = -1;
int min0 = calculate(tree.children.get(0));
int min1 = calculate(tree.children.get(1));
if (min0 != -1 && (min == -1 || min > min0))
min = min0;
if (min1 != -1 && (min == -1 || min > min1))
min = min1;
if (min == -1)
return -1;
if (value0 && tree.operator == 0)
min++;
if (!value0 && tree.operator == 1)
min++;
return min;
}
}