zoukankan      html  css  js  c++  java
  • FZU1061 矩阵连乘

     Problem Description  链接

    给定n个矩阵{A1,A2,...,An},考察这n个矩阵的连乘积A1A2...An。由于矩阵乘法满足结合律,故计算矩阵的连乘积可以有许多不同的计算次序,这种计算次序可以用加括号的方式来确定。

    矩阵连乘积的计算次序与其计算量有密切关系。例如,考察计算3个矩阵{A1,A2,A3}连乘积的例子。设这3个矩阵的维数分别为10*100,100*5,和5*50。若按(A1A2)A3计算,3个矩阵连乘积需要的数乘次数为10*100*5+10*5*50 = 7500。若按A1(A2A3)计算,则总共需要100*5*50+10*100*50 = 75000次数乘。

    现在你的任务是对于一个确定的矩阵连乘方案,计算其需要的数乘次数。

     Input

    输入数据由多组数据组成。每组数据格式如下:
    第一行是一个整数n (1≤n≤26),表示矩阵的个数。
    接下来n行,每行有一个大写字母,表示矩阵的名字,后面有两个整数a,b,分别表示该矩阵的行数和列数,其中1<a,b<100。
    第n+1行是一个矩阵连乘的表达式,由括号与大写字母组成,没有乘号与多余的空格。如果表达式中没有括号则按照从左到右的顺序计算,输入的括号保证能够配对。

     Output

    对于每组数据,输出仅一行包含一个整数,即将该矩阵连乘方案需要的数乘次数。如果运算过程中出现不满足矩阵乘法法则的情况(即左矩阵列数与右矩阵的行数不同),则输出“error”。

     Sample Input

    3 A 10 100 B 100 5 C 5 50 A(BC)

     Sample Output

    75000
    #include <iostream>
    #include <string>
    #include <deque>
    using namespace std;
    
    /*
        思路:使用STL双端队列做,分俩轮处理
        第一轮:先把括号的内序列处理,因为考虑括号可能叠加(()),于是每次碰见)就将一个括号内的序列找出来计算,并将结果放回序列中
        第二轮:因为括号都处理了,只要依次左乘即可
        注意:如果不合乎矩阵的行列跳出即可
    */
    
    //矩阵
    struct Matrix
    {
        int row, lie;
    };
    
    int main()
    {
        Matrix ms[28];
    
        int n, row, lie;
        char name;
        string xl; //存放输入序列
        while (cin >> n)
        {
            while (n--)
            {
                cin >> name >> row >> lie;
                ms[name - 'A'].row = row;
                ms[name - 'A'].lie = lie;
            }
            getchar();
            //获取序列
            getline(cin, xl);
            long long sum = 0;
            deque<char> dq;
            //第一轮 过滤括号
            for (int i = 0; i < xl.size(); i++)
            {
                if (xl[i] != ')')
                {
                    dq.push_back(xl[i]);
                }
                //因为括号满足条件
                else
                {
                    string s;
                    while (dq.back() != '(')
                    {
                        s += dq.back();
                        dq.pop_back();
                    }
                    dq.pop_back();
    
                    //如(ABC) 出队列的时候的时候是CBA
                    //于是后往前乘 ABC
                    for (int j = s.size() - 1; j > 0; j--)
                    {
                        int m1 = s[j] - 'A';     //第一个矩阵
                        int m2 = s[j - 1] - 'A'; //第二个矩阵
                        if (ms[m1].lie != ms[m2].row)
                        {
                            //不符合矩阵规则标记
                            sum = -1;
                            break;
                        }
                        sum += ms[m1].row * ms[m1].lie * ms[m2].lie;
                        //新的矩阵存放在第二个矩阵中迭代
                        ms[m2].row = ms[m1].row;
                    }
                    //乘完的矩阵放回序列
                    dq.push_back(s[0]);
                    if (sum == -1)
                        break;
                }
            }
            if (sum != -1)
            {
                //处理正常序列
                string s;
                while (dq.size())
                {
                    s += dq.front();
                    dq.pop_front();
                }
                for (int j = 0; j < s.size() - 1; j++)
                {
                    int m1 = s[j] - 'A';
                    int m2 = s[j + 1] - 'A';
                    if (ms[m1].lie != ms[m2].row)
                    {
                        sum = -1;
                        break;
                    }
                    sum += ms[m1].row * ms[m1].lie * ms[m2].lie;
                    ms[m2].row = ms[m1].row;
                }
                if (sum != -1)
                {
                    cout << sum << endl;
                    continue;
                }
            }
            cout << "error" << endl;
        }
    }
  • 相关阅读:
    弹出消息对话框ScriptManager
    DataTable 转成字符串数组
    用XmlSerializer进行xml反序列化的时候,程序报错: 不应有 <xml xmlns=''>
    意外的节点类型 Element。只能在简单内容或空内容上调用 ReadElementString 方法
    case when 对某个字段值分类讨论
    sql语句求百分比
    分页Sql语句
    数据库,ADO.NET(ADO),Oledb(Odbc)和编程语言关系框架图
    UIView的alpha、hidden和opaque属性之间的关系和区别
    IOS 入门开发之创建标题栏UINavigationBar的使用
  • 原文地址:https://www.cnblogs.com/dlvguo/p/12680238.html
Copyright © 2011-2022 走看看