ZOJ-1094矩阵相乘次数计算

题目链接

算法分析与设计——以ACM程序设计为例——P28矩阵相乘次数

解决此题,须知道三项矩阵相乘基本知识:A*B 矩阵相乘
1:需满足A的列数等于B的行数。
2:矩阵相乘次数=A的行数 *B的行数 *B的列数
3:矩阵结果的行数=A的行数,列数=B的列数
算法描述:
1:构造数据结构:
结点:代表一个矩阵的行列数
struct Node {
int row, col;
};

映射:将矩阵名称与相应行列数联系起来
map<char, Node> matrix;

堆栈:用来将输入的表达式中的矩阵(名称)压入,方便计算
stack array;

2输入相关数据
cin >> n;
for (i = 0; i < n; i++) { //输入名称和相应的行列数
cin >> Name;
cin>> matrix[Name].row >> matrix[Name].col;
}
采用先输入名称,接着利用映射输入相关行列数(曾经试过一次性全部输入,但vs2019好像有点问题,你运气好的话应该也可以一次性输入)
3 计算每一个表达式
输入exp要计算的表达式(须有括号,否则无法计算)
分三种情况
a:如果exp[i]是矩阵(名称),直接将它(或者说映射出来的行列数)压入array堆栈中(由此可见array中的矩阵(字母)是原表达式中的倒序,如(AB),在堆栈中从头到尾是BA,这很重要,否则答案会一直错误,别问我怎么知道的)
b:exp[i]==’(‘时,很简单,直接continue省略他,进入下一层循环。
c:exp[i]=’)'时,事儿最多,需要做的是,弹出array栈顶两个结点(比如先弹出a,后弹出b),并进行相乘,规则和上面一开始讲的一样,不再赘述,容易出错的是,计算时应按b*a来算(具体原因请看a中括号部分,因为这个笔者曾被气得xxx),如果满足b的列数等于a的行数,则将矩阵相乘次数记录下来(不等,直接break)。矩阵相乘的新矩阵行数列数(计算方法见最上面三个基本知识)压入堆栈中。

执行到表达式最后一个字符时,将计算总数count输出。最后大功告成!!!

#include<iostream>
#include<map>
#include<stack>
using namespace std;
struct Node {
	int row, col;
};
map<char, Node> matrix;			//将矩阵名称与相应行列数进行映射
int main() {
	int n, i;
	char Name;
	string exp;
	cin >> n;
	for (i = 0; i < n; i++) {			//输入名称和相应的行列数
		cin >> Name;
			cin>> matrix[Name].row >> matrix[Name].col;
	}
	while (cin>>exp)
	{
	
		stack<Node> array;				//用堆栈记录所有矩阵行数和列数
		int count = 0;
		for (i = 0; i < exp.size(); i++) {
			if (exp[i] == '(')continue;
			else if (exp[i] == ')')
			{
				Node a = array.top();
				array.pop();
				Node b = array.top();
				array.pop();
				if (b.col != a.row) { 
					cout << "error" << endl; break; }
				count += b.row * a.col * a.row;
				Node tmp = { b.row,a.col };
				array.push(tmp);
			}
			else {
				array.push(matrix[exp[i]]);
			}
		}
		if (i == exp.size())cout << count << endl;
	}
	return 0;
}

输入样例:
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))

结果展示

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值