嗯,今天要刷的水题是一道看起来很难的题目,因为当我们看到矩阵的时候难免会有‘一阵阵的恶心’,但是再仔细读了题意之后就会发现,这是一道很辣鸡的水题。
仔细瞅瞅
发现本题的关键就是解析表达式,而比较简单的解析表达式可以借助栈来完成。
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <stack>
using namespace std;
struct Matrix{
int a,b;
Matrix(int a=0, int b=0):a(a),b(b) {} //定义一个结构体,这一步是构造函数
}m[26];
stack<Matrix> s;
int main()
{
int n;
cin >> n;
for(int i = 0; i < n; i++){
string name;
cin >> name;
int k = name[0] - 'A';
cin >> m[k].a >> m[k].b;
} //嗯,这样就读入了数据
string expr;
while(cin >> expr) {
int len = expr.length(); //用len来保存长度
bool error = false;
int ans = 0;
for(int i = 0; i < len; i++){
if( isalpha(expr[i]) ) s.push(m[expr[i] - 'A']);
else if(expr[i] == ')') {
Matrix m2 = s.top(); s.pop();
Matrix m1 = s.top(); s.pop();
if (m1.b != m2.a){ error = true; break; }
//若A的行数不等于B的列数,则乘法无法运行
ans += m1.a * m1.b * m2.b;
s.push(Matrix(m1.a, m2.b));
} //当我们遇到右括号时出栈并计算,然后结果入栈
}
if(error) printf("error\n");
else printf("%d\n", ans);
}
return 0;
}
|
注意到底下的算式中每两个需要相乘的矩阵都会放在一个括号中,不会出现(ABC)这样的算式。因此,每遇到一个右括号就代表要将括号之前的两个矩阵进行矩阵乘法。我们可以使用一个栈来模拟这个过程:
- 右括号 : 不用搭理它
- 矩阵名称 : 压栈
- 右括号 : 弹出栈中的前两个,进行乘法运算,将结果压栈
由此便可以模拟整个表达式的计算过程。我们可以用一个 pair 来表示矩阵的行数和列数,矩阵乘法的过程请参考《线性代数》。在前面的 res 函数中计算结果,如果遇到了没法相乘的矩阵就输出 error。这个函数可以计算结果矩阵的行数和列数并返回相乘的总次数。我们只需要将结果加起来就可以得到结果了。另外,如果表达式只有一个矩阵的话,表达式长度必为 1,直接输出结果 0。