紫书第六章例题6-3
已知矩阵
并设矩阵
则
矩阵 C 共有 m 行 n 列,求得每一项都需要计算 l 次乘法,所以计算如上的 AB 需要计算 m × l × n 次乘法。
经检验,测试数据的每一层括号在每做一次矩阵乘法以后都只有两个矩阵,或者不做矩阵乘法也只有两个矩阵。因此,只需要在输入过程中忽略左括号,遇到矩阵时存入 stack 中,遇到右括号时计算 stack 最顶端的两个矩阵相乘,并弹出这两个矩阵,将计算结果压入栈顶即可。读取到换行符时,输出结果。如果矩阵 A 的列不等于矩阵 B 的行,则按照矩阵乘法的定义,AB 无法计算。此时直接输出 error 并放弃剩余数据。
每次输出以后,需要将栈清空,存储答案的变量 ans 要置零。如果因为无法计算而放弃剩余内容,需要读掉该行剩下的字符。读入过程中,为了确保读到表示矩阵的字母,需要先读掉上一行的回车符 \n 。
AC 代码(0 ms):
#include<cstdio>
#include<cstdlib>
#include<stack>
#include<cctype>
#include<string>
#pragma warning(disable:4996)
using namespace std;
struct matrix { unsigned long long r, c; };
stack<matrix> s; matrix m[26], M, N, R; unsigned char n; char c;
bool exitfor; unsigned long long ans = 0;
int main() {
scanf("%hhu", &n);
for (unsigned char i = 0; i < n; ++i) {
getchar(); scanf("%c%llu%llu", &c, &m[i].r, &m[i].c);
}
getchar();
for (;;) {
c = getchar();
switch (c) {
default:s.emplace(m[c - 65]); break;
case '(':break;
case ')':N = s.top(); s.pop(); M = s.top(); s.pop();
switch (M.c == N.r) {
case true:ans += M.r * M.c * N.c; R.r = M.r, R.c = N.c; s.emplace(R); break;
case false:puts("error"); ans = 0;
while (getchar() != '\n') {} while (s.empty() == false) { s.pop(); }
}
break;
case '\n':printf("%llu\n", ans); ans = 0; while (s.empty() == false) { s.pop(); } break;
case EOF:exitfor = true;
}
if (exitfor == true)break;
}
return 0;
}