套路还在——矩阵计算估值

描述

矩阵乘法的运算量与矩阵乘法的顺序强相关。


例如:

    A是一个50×10的矩阵,B是10×20的矩阵,C是20×5的矩阵

计算A*B*C有两种顺序:((AB)C)或者(A(BC)),前者需要计算15000次乘法,后者只需要3500次。

编写程序计算不同的计算顺序需要进行的乘法次数

知识点 字符串
运行时间限制 10M
内存限制 128
输入

输入多行,先输入要计算乘法的矩阵个数n,每个矩阵的行数,列数,总共2n的数,最后输入要计算的法则

3       //矩阵个数n 
50 10   //矩阵A的行数50,列数10
10 20   //矩阵B的行数10,列数20
20 5    //矩阵C的行数20,列数5
(A(BC)) //矩阵从A开始命名,A、B、C、D...以此类推,通过括号表示运算顺序
 

输出

输出需要进行的乘法次数

样例输入 3 50 10 10 20 20 5 (A(BC))
样例输出 3500

今天又开始写华为题目了。一道题让我好激动。对于一个比较复杂的题目,竟然一下就通过了,用到了栈的知识,也算是活学活用了吧。代码冗余度高,最近确实没什么心情改。

太激动,直接上代码:

#include <stdio.h>
#include <vector>
#include <math.h>
#include <string>
#include <iostream>
#include <string>
#include <stack>

using namespace std;


struct xy{
    int x;
    int y;
};


int main()
{
    int n = 0;;
    while (cin>>n)
    {
        stack<char> s;
        vector<xy> mat;
        for (int i = 0; i < n; i++)
        {
            int tmpx = 0, tmpy = 0;
            cin >> tmpx >> tmpy;
            xy tmpxy{ tmpx, tmpy };
            mat.push_back(tmpxy);
        }
        xy nowxy{ 1, 1 };
        string str;
        cin >> str;//以上是题目的输入
        int res = 0;//输出的结果
        int times = 0;//计算的次数
        //思路是:计算一次就再保存一次结果
        for (int i = 0; i < str.size(); i++)
        {
            if (str[i] != ')')//如果不是后括号就一直push
            {
                s.push(str[i]);
            }
            else//遇到一个后括号的处理
            {
                stack<char> tmps;
                while (s.top() != '(')//一直pop,pop到前括号为止
                {
                    tmps.push(s.top());
                    s.pop();
                }
                s.pop();//pop出前括号,为了后面对称处理
                vector<char> forcount;//这里申请一个vector,是因为括号内不一定只有两个元素,可能是ABCD这种,就要顺序计算
                while (!tmps.empty())//还是利用栈的方法,把tmps的pop出来就是正确的顺序了。就想两个栈实现一个队列的思路一样,一个栈进去后出来再进另一个栈,再出来就是队列了。
                {
                    forcount.push_back(tmps.top());
                    tmps.pop();
                }
                int sum = 0;//发现ABCD的计算规律。其实就是第一个矩阵的行不断乘以后面矩阵的行和列,全部加起来就行
                for (int i = 1; i < forcount.size(); i++)
                {
                    sum += mat[forcount[0] - 'A'].x*mat[forcount[i] - 'A'].x*mat[forcount[i] - 'A'].y;
                }
                nowxy.x = mat[forcount[0] - 'A'].x; nowxy.y = mat[forcount[forcount.size()-1] - 'A'].y;//计算完后产生一个新矩阵,记录它的行列
                mat.push_back(nowxy);//把新的行列也放进去
                s.push('A' + n-1 + (++times));//假设开始是ABC,那么新进去就是D,以此类推
                res += sum;
            }
            
        }
        cout << res << endl;
    }

    return 0;
}
原文地址:https://www.cnblogs.com/wyc199288/p/6184714.html