描述 |
矩阵乘法的运算量与矩阵乘法的顺序强相关。
A是一个50×10的矩阵,B是10×20的矩阵,C是20×5的矩阵 计算A*B*C有两种顺序:((AB)C)或者(A(BC)),前者需要计算15000次乘法,后者只需要3500次。 编写程序计算不同的计算顺序需要进行的乘法次数 |
---|---|
知识点 | 字符串 |
运行时间限制 | 10M |
内存限制 | 128 |
输入 |
输入多行,先输入要计算乘法的矩阵个数n,每个矩阵的行数,列数,总共2n的数,最后输入要计算的法则 3 //矩阵个数n |
输出 |
输出需要进行的乘法次数 |
样例输入 | 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; }