思路:构造一颗二叉树,递归计算左右子树的计算量, 再加上左子树矩阵*右子树矩阵的计算量。
坑:测试数据存在右括号多于左括号数量的情况,需要特殊处理一下。
import java.util.*;
public class Main {
public class Node {
Node left, right;
int row, col;//val
public Node(int x, int y) {
row = x;
col = y;
left = null;
right = null;
}
}
public Node creatTree(char[] s, int[][] a, int start, int end) {
if(start > end || start < 0 || start >= s.length || end < 0 || end >= s.length)
return null;
if(start == end) {
int idx = s[start] - 'A';
return new Node(a[idx][0], a[idx][1]);
}
int l = start + 1, r = end - 1;
int cnt = 1, mid = l;
if(s[l] == '(') {
while(cnt != 0) {
mid++;
if(s[mid] == '(') cnt ++;
if(s[mid] == ')') cnt --;
}
}
Node root = new Node(-1,-1);
root.left = creatTree(s, a, l, mid);
root.right = creatTree(s, a, mid+1, r);
return root;
}
public int[] dfs(Node root) {
if(root == null) return new int[] {-1,-1, 0};
if(root.left == null && root.right == null) {
int[] res = new int[] {root.row, root.col, 0};
//System.out.println(Arrays.toString(res));
return res;
}
int[] l = dfs(root.left);
int[] r = dfs(root.right);
int[] res = new int[] {l[0], r[1], l[2] + r[2] + l[0]*l[1]*r[1]};
return res;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Main mn = new Main();
while(sc.hasNext()) {
int n = sc.nextInt();
int[][] a = new int[n][2];
for(int i=0; i < n; i++) {
a[i][0] = sc.nextInt();
a[i][1] = sc.nextInt();
}
char[] s = sc.next().toCharArray();
int cnt = 0;//判断左括号数量是否等于右括号数量
for(int i=0; i < s.length; i++) {
if(s[i] == '(') cnt ++;
if(s[i] == ')') cnt --;
}
Node tree = null;
if(cnt != 0) {
tree = mn.creatTree(s, a, 0, s.length-2); // 去除多余的一个右括号
} else {
tree = mn.creatTree(s, a, 0, s.length-1);
}
int[] res = mn.dfs(tree);
System.out.println(res[2]);
}
}
}
/*
1. 构造二叉树,节点信息包括:row(行数),col(列数)
2. 计算子树乘法次数,再加上左子树矩阵*右子树矩阵的计算量。
*/