作者:JF
题目描述
给定一个矩阵相乘的表达式,计算矩阵相乘的次数。例如,假设A是50*10矩阵,B是10*20矩阵,C是20*5矩阵。计算A*B*C有两种不同的策略,即(A*B)*C和A*(B*C)。第一个需要15000个初等乘法,但第二个只需要3500个。
先输入一个整数N,然后输入N个矩阵的信息,矩阵名称,矩阵的行列数。接着给出一些表达式,输出表达式所需的相乘次数,如果表达的计算因矩阵不匹配而导致错误,则输出“error”。
输入输出样例
输入
9
A 50 10
B 10 20
C 20 5
D 30 35
E 35 15
F 15 5
G 5 10
H 10 20
I 20 25
A
B
C
(AA)
(AB)
(AC)
(A(BC))
((AB)C)
(((((DE)F)G)H)I)
(D(E(F(G(HI)))))
((D(EF))((GH)I))
输出
0
0
0
error
10000
error
3500
15000
40500
47500
15125
思路
用map来保存每个矩阵名到矩阵行列的映射关系,对于输入的表达式,如果长度为1则直接输入0,否则依次遍历整个表达式,遇到‘(’和大写字母直接入栈,遇到‘)’计算栈顶两个矩阵的相乘次数,依次累加,并将一个新的矩阵入栈(新矩阵行列由第一个矩阵的行和第二个矩阵的列构成,名称为当前遍历的序号i)。
注意点
1.注意两矩阵相乘的前后顺序。
2.计算完两矩阵相乘次数后先把原矩阵和‘(’出栈,在将新矩阵入栈。
3.每次初始化相乘的次数和error的判断标志。
AC代码
#include "bits/stdc++.h"
using namespace std;
int main()
{
int n;
cin>>n;
map<string,pair<int,int>> matrix; //存储矩阵信息
while (n--)
{
string x;
int a,b;
cin>>x>>a>>b;
matrix[x]= make_pair(a,b);
}
string str;
while(cin>>str)
{
if(str.length()==1){
cout<<"0"<<endl;
continue;
}
stack<string> stack;
int ans=0; //统计计算次数
int flag=0; //判断是否error
pair<int,int> temp= make_pair(0,0); //temp变量记录初次出栈矩阵的信息
for(int i=0;i<str.length();i++)
{
if(str[i]!=')') stack.push(str.substr(i,1)); //入栈
else{
while (stack.top()!="(")
{
if(temp== make_pair(0,0)){
temp=matrix[stack.top()];
}
else{
if(matrix[stack.top()].second==temp.first){ //矩阵可以相乘
ans=ans+matrix[stack.top()].first*temp.second*temp.first;
string t= to_string(i);
//存储新矩阵信息
matrix[t]= make_pair(matrix[stack.top()].first,temp.second);
stack.pop(); //将以计算过的矩阵和‘(’一起出栈
stack.pop();
stack.push(t); //将新矩阵入栈
temp= make_pair(0,0);
break;
}
else{ //矩阵不可相乘,输出error
cout<<"error"<<endl;
flag=1;
break;
}
}
stack.pop();
}
}
if(flag) break;
}
if(!flag)
cout<<ans<<endl;
}
}