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


    描述

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


    例如:

        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;
    }
  • 相关阅读:
    Linux 基础命令3 shell
    Django 的学习(2) 从adminuser到配置
    Linux巨好用的
    常见任务&基本工具 1 软件包管理
    java学习补全 1
    基础命令1
    java 5 绘图GUI
    Open GL与OpenGLES
    NDK 安装步骤
    转:为什么要有handler机制?
  • 原文地址:https://www.cnblogs.com/wyc199288/p/6184714.html
Copyright © 2020-2023  润新知