題目內容
矩陣乘法的運算量與矩陣乘法的順序強相關。
例如:
A是一個50×10的矩陣,B是10×20的矩陣,C是20×5的矩陣
計算ABC有兩種順序:((AB)C)或者(A(BC)),前者需要計算15000次乘法,后者只需要3500次。
編寫程序計算不同的計算順序需要進行的乘法次數
輸入描述:
輸入多行,先輸入要計算乘法的矩陣個數n,每個矩陣的行數,列數,總共2n的數,最后輸入要計算的法則
輸出描述:
輸出需要進行的乘法次數
示例1
輸入
3
50 10
10 20
20 5
(A(BC))
輸出
3500
思路
顯然用棧做。但是細節要把控好。
考慮這樣的數據,代碼也應該能handle:
4
50 10
10 20
20 5
5 6
(A(BCD))
輸出
9000
思路:
每個字母肯定不會重復,每個字母對應到一個(r,c)元組上,弄成結構體比較方便。
將字母括號串從左到右掃描,遇到')'則彈棧,一直彈到遇到'(',那么彈出的這些字母(對應到一個個矩陣,也對應到一個包含(r,c)維度信息的結構體),它們的列數c相乘,再乘以最后彈出元素(也即緊鄰'('右邊的字母)的行數r。
注意,這里還沒有結束,遇到了'('應該把彈出這些元素計算結果進行保存,並且,更新一下維護的字母括號序列的元素,我的做法是把原有的“(XXXXZ)”這個東西用Z來替代,因為Z的列數c后續還是會被使用。
放碼過來
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <climits>
#include <stack>
using namespace std;
void EX21_clean() {
int n;
struct Dim { int r, c; };
while (cin >> n) {
vector<Dim> vd;
Dim dim;
for (int i = 0; i < n; i++) {
cin >> dim.r >> dim.c;
vd.push_back(dim);
}
string s; cin >> s;
stack<Dim> stk;
int ans = 0;
stack<char> cal;
int delta;
int idx;
char ch1, ch2;
for (int i = 0; i < s.length(); i++) {
if (s[i] == ')') {
if (cal.size() != 1) {
ch1 = cal.top(); cal.pop();
if (ch1 == '(') {
continue;
}
idx = ch1 - 'A';
dim = vd[idx];
delta = dim.c;
while (!cal.empty()) {
ch2 = cal.top(); cal.pop();
idx = ch2 - 'A';
if (ch2 == '(') {
cal.push(ch1); //注意此處
break;
}
dim = vd[idx];
delta *= dim.c;
}
delta *= dim.r;
ans += delta;
}
}
else {
cal.push(s[i]);
}
}
cout << ans << endl;
}
}
int main() {
//EX1();
//EX2();
//EX3();
//EX4();
//EX5();
//EX6();
//EX7();
//EX11();
//EX12();
//EX13();
//EX14();
//EX15();
//EX16();
//EX17();
EX21_clean();
return 0;
}