题意:输入n个矩阵的维度和一些矩阵链乘表达式,输出乘法的次数。如果乘法无法进行,输出error。假定A是m*n,B是n*p的矩阵,那么A*B是m*p矩阵,乘法次数为m*n*p。假定A的列数不等于B的行数,则乘法无法进行。
例如,A是50*10的,B是10*20的,C是20*5的,则(A(BC))的乘法次数为10*20*5(BC的乘法次数)+50*10*5((A(BC)))的乘法次数 = 3500
分析:本题的关键是解析表达式。本题的表达式比较简单,可以用一个栈来完成:遇到字母时入栈,遇到右括号时出栈并计算,然后结果入栈。因为输入保证合法,括号无需入栈。
以上内容来自算法竞赛入门经典。
补充:如果碰到右括号那么就拿出两个元素计算,计算结果放回去,模拟即可。
#include<bits/stdc++.h> using namespace std; int n; char str[1005]; struct Matrix { int r, c; Matrix(int _r = 0, int _c = 0): r(_r), c(_c) {} }a[26]; int main() { scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%s", str); int id = str[0] - 'A'; scanf("%d%d", &a[id].r, &a[id].c); } while (~scanf("%s", str)) { int ans = 0, len = strlen(str); stack<Matrix> S; for (int i = 0; i < len; i++) { if (isalpha(str[i])) S.push(a[str[i]-'A']); else if (str[i] == ')') { Matrix m2 = S.top(); S.pop(); Matrix m1 = S.top(); S.pop(); if (m1.c != m2.r) { ans = -1; break; } ans += m1.r * m1.c * m2.c; S.push(Matrix(m1.r, m2.c)); } } if (ans == -1) printf("error\n"); else printf("%d\n", ans); } return 0; }