http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1094
编程任务:对于给定的矩阵相乘顺序,计算矩阵相乘的乘法次数。
注:题目输入的第二部分严格遵守题目中描述的语法
算法分析:
1、 采用递归的方法求解
分两种情况:
- 遇到左括号‘(’
表示遇到这种情况:(expr1,expr2),计算expr1,expr2,通过递归可得到矩阵名称,计算过程中需跳过右括号
2.不是左括号‘(’,那就是矩阵名称,返回该名称
View Code
#include<stdio.h> #include<string.h> struct Node { int row,col,mults; }data[27]; int pos,flag; char str[101]; Node Expression() { Node tmp1,tmp2,tmp; if(flag) { if(str[pos]=='(') { pos++; tmp1 = Expression(); //获取表达式1 tmp2 = Expression(); //获取表达式2 pos++; if(tmp1.col != tmp2.row) //不能相乘,结束 { flag = 0; return tmp1; } tmp.row = tmp1.row; tmp.col = tmp2.col; //计算乘法次数 tmp.mults = tmp1.mults+tmp2.mults+tmp1.row * tmp1.col * tmp2.col; } else //是矩阵 { tmp.row = data[str[pos]-'A'].row; tmp.col = data[str[pos]-'A'].col; tmp.mults = 0; pos++; //跳到下一个位置 } } return tmp; } int main() { int n,row,col; char ch; Node ans; scanf("%d\n",&n); while(n--) { scanf("%c%d%d\n",&ch,&row,&col); data[ch-'A'].row = row; data[ch-'A'].col = col; } while(scanf("%s",str)!=EOF) { pos = 0; flag = 1; ans = Expression(); if(!flag) printf("error\n"); else printf("%d\n",ans.mults); } return 0; }
2、 用栈模拟进行求解:遇到矩阵就进栈,遇到右括号就将栈顶的练个矩阵相乘,并将结果进栈
View Code
#include<iostream> #include<cstdio> #include<stack> #include<cstring> using namespace std; struct Node { int row,col; }data[27]; int main() { int n,row,col,i,len,flag,ans; char ch,str[101]; Node tmp1,tmp2,tmp; scanf("%d\n",&n); while(n--) { scanf("%c%d%d\n",&ch,&row,&col); data[ch-'A'].row = row; data[ch-'A'].col = col; } while(scanf("%s",str)!=EOF) { stack<Node>Q; len = strlen(str); flag = 1; ans = 0; for(i = 0; i < len; i++) { if(str[i] == '(') continue; //遇到左括号,继续 if(str[i] == ')') //遇到右括号,从栈中取出两个表达式的计算值 { tmp2 = Q.top(); Q.pop(); tmp1 = Q.top(); Q.pop(); if(tmp1.col != tmp2.row) //两个矩阵不能相乘,结束 { printf("error\n"); break; } ans += tmp1.row * tmp1.col * tmp2.col; //累加计算结果 tmp.row = tmp1.row; tmp.col = tmp2.col; Q.push(tmp); //将计算的值进栈 } else Q.push(data[str[i]-'A']); //如果是表达式,矩阵入栈 } if(i == len) printf("%d\n",ans); } return 0; }