矩陣乘法的運算量計算(華為OJ)

weixin_33766168發表於2017-08-13

題目地址:
https://www.nowcoder.com/practice/15e41630514445719a942e004edc0a5b?tpId=37&&tqId=21293&rp=1&ru=/activity/oj&qru=/ta/huawei/question-ranking

題目內容

矩陣乘法的運算量與矩陣乘法的順序強相關。

例如:
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;
}

相關文章