输入n个矩阵的维度和一些矩阵链乘表达式,输出乘法的次数。如果乘法无法进行,输出error。假定A是mn矩阵,B是np矩阵,那么AB是mp矩阵,乘法次数为mnp。如果A的列数不等于B的行数,则乘法无法进行。
例如,A是5010的,B是1020的,C是205的,则(A(BC))的乘法次数为10205(BC的乘法次数)+ 50105((A(BC))的乘法次数)= 3500。
import java.io.*;
import java.util.*;
interface Printer {
void p(Object... o);
void pn(Object... o);
default String format(Object... o) {
String format;
if (o.length == 1) {
format = o[0].toString();
} else {
Object[] dest = new Object[o.length - 1];
System.arraycopy(o, 1, dest, 0, dest.length);
format = String.format(o[0].toString(), dest);
}
return format;
}
}
class MyPrinter implements Printer {
@Override
public void p(Object... o) {
printToFile(false, o);
System.out.print(format(o));
}
@Override
public void pn(Object... o) {
printToFile(true, o);
if (o == null || o.length == 0) {
System.out.println();
} else {
System.out.println(format(o));
}
}
private void printToFile(boolean nl, Object... o) {
if (writer == null) {
return;
}
try {
if (o.length != 0) {
writer.write(format(o));
}
if (nl) {
writer.write("\n");
}
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private static FileWriter writer;
static {
if ("true".equals(System.getenv("OUTPUT_TO_LOCAL"))) {
try {
writer = new FileWriter("D:\\output.txt");
writer.write("");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
solution(System.in, new MyPrinter());
}
private static int totalCount = 0;
public static void solution(InputStream in, Printer p) {
Scanner scanner = new Scanner(in);
int mCount = scanner.nextInt();
scanner.nextLine();
HashMap<Character, Matrix> ms = new HashMap<>();
while (mCount -- > 0) {
Matrix m = Matrix.parse(scanner.nextLine());
ms.put(m.name, m);
}
while (scanner.hasNextLine()) {
LinkedList<Character> stack = new LinkedList<>();
LinkedList<Matrix> mStack = new LinkedList<>();
totalCount = 0;
if (!calculate(scanner.nextLine(), stack, mStack, ms)) {
p.pn("error");
} else {
p.pn(totalCount);
}
}
}
private static boolean calculate(String line, LinkedList<Character> stack, LinkedList<Matrix> mStack, HashMap<Character, Matrix> ms) {
char[] exp = line.toCharArray();
for(char c : exp) {
if (c == ')') {
if (!updateResult(stack, mStack, ms)) {
return false;
}
} else {
stack.push(c);
}
}
while (!stack.isEmpty()) {
mStack.push(ms.get(stack.pop()));
}
return multiplyAll(stack, mStack, ms);
}
private static boolean updateResult(LinkedList<Character> stack, LinkedList<Matrix> mStack, HashMap<Character, Matrix> ms) {
while (true) {
char c1 = stack.pop();
if (c1 == '(') {
break;
}
mStack.push(ms.get(c1));
}
return multiplyAll(stack, mStack, ms);
}
private static boolean multiplyAll(LinkedList<Character> stack, LinkedList<Matrix> mStack, HashMap<Character, Matrix> ms) {
if (!mStack.isEmpty()) {
Matrix m = mStack.pop();
while (!mStack.isEmpty()) {
Matrix mm = mStack.pop();
m = multiply(m, mm);
if (m == null) {
return false;
}
}
stack.push(m.name);
ms.put(m.name, m);
}
return true;
}
private static Matrix multiply(Matrix m1, Matrix m2) {
if (m1.c != m2.r) {
return null;
}
totalCount += m1.r * m2.c * m1.c;
return new Matrix(nextChar(), m1.r, m2.c);
}
static char next = 'Z' + 1;
private static char nextChar() {
return next ++;
}
}
class Matrix {
char name;
int r, c;
public Matrix(char name, int r, int c) {
this.name = name;
this.r = r;
this.c = c;
}
static Matrix parse(String raw) {
String[] parts = raw.split(" ");
return new Matrix(parts[0].charAt(0), Integer.parseInt(parts[1]), Integer.parseInt(parts[2]));
}
}