Logic Expression Tree

题目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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值