Uva 442 Matrix Chain Multiplication

本文介绍了一种使用栈来高效计算给定序列中矩阵乘法次数的方法。通过两次遍历输入序列,并利用栈存储待计算的矩阵,可以有效地处理括号嵌套的情况。文章还提供了完整的代码实现及注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

点击打开链接http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=383

题目意思:给定一序列的矩阵,然后对于每一个表达式求出矩阵的乘法次数


解题思路:我们可以想到利用栈的思想,如果读入的字符不是 ')' 那么我们都把它如栈,如果遇到')', 我们往回找到第一个不是左括号后面的所有矩阵然后相乘,在把结果如栈即可


注意事项:由于后面的乘法会改变值,所以我们必须开两个结构体,一个用来存放初始值,另外一个是作为计算是所用,这样就不会有错,还有这一题数据很水,如果直接考虑括号内只有两个矩阵也可以过

#include <cstdio>
#include <cstring>
#include <iostream>
#include <stack>
#include <algorithm>
using namespace std;
int n , sum;
char ch[100];
//结构体用来存储行数和列数
struct Matrix{
    int row;
    int col;
};

Matrix s[200];//存储输入的值
Matrix cs[200];//如果不开两个会有数据出错
stack<char>st;

//复制到另外一个结构体里面
void copy(){
    for(int i = 1 ;i <= n ; i++)
        cs[i] = s[i];
}

void solve(){
    int i = 0 , mark = 0;
    sum = 0;
    copy();
    while(ch[i]){
        //如果不是有括号就入栈
        if(ch[i] != ')')
            st.push(ch[i]);
        else{
            //建立一个临时的栈用来存储要计算的那一部分
            stack<char>temp;
            while(!temp.empty())
                temp.pop();
            //第一个左括号之前全部入栈
            while(st.top() != '('){
                temp.push(st.top());
                st.pop();
            }
            st.pop();//同时删除一个左括号
            //tempchar 表示第一个矩阵
            char tempchar;
            if(!temp.empty())
                tempchar = temp.top();
            temp.pop();
            //计算矩阵的乘法次数
            while(!temp.empty()){
                //如果两个矩阵不满足乘法就输出error
                if(cs[tempchar-64].col != cs[temp.top()-64].row){
                     printf("error\n");
                     mark = 1;
                     break;
                }
                else{
                    //这里都要对cs结构体操作,因为乘法后会改变原来的值
                    sum += cs[tempchar-64].row * cs[tempchar-64].col * cs[temp.top()-64].col;
                    cs[tempchar-64].col = cs[temp.top()-64].col;
                    temp.pop();
                }
            }
            if(mark)
                break;
            st.push(tempchar);//最后一个矩阵从新入栈
        }
        i++;
    }
    if(!mark)
        cout<<sum<<endl;
    //栈的清空
    while(!st.empty())
        st.pop();
}

//main函数实现
int main(){
    int  i;
    char c;
    cin>>n;
    getchar();
    for(i = 1 ; i <= n ; i++){
        cin>>c>>s[i].row>>s[i].col;
    }
    getchar();
    while(gets(ch)){
        //只有一个矩阵就直接输出error
        if(strlen(ch) == 1)
            cout<<0<<endl;
        else
            solve();
    }
    return 0;
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值