Sample Input
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))
Sample Output
0
0
0
error
10000
error
3500
15000
40500
47500
15125
一开始的思路是用链表存放每个矩阵的行、列、字母,然后把字母入栈,根据字母来找对应的矩阵,程序写出来后虽然能过样例,但是却无法AC,而且代码又长,时间并不是很宽裕就放弃原先的思路去学习刘汝佳老师的代码
自己写的代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
using namespace std;
typedef struct multi* mt;
struct multi
{
int m;
int n;
char c;
mt next;
multi() : next(NULL) {}
};
stack<char> pt;
char order;
int sum = 0, flag = 0, n, nl;
mt head = new struct multi(), p1 = NULL;
mt find(char c) {//根据字母来查找对应的矩阵
p1 = head;
while (p1 != NULL) {
if (p1->c == c) {
return p1;
}
p1 = p1->next;
}
}
void Insert(mt temp) { //新乘出来的矩阵插入链表末尾
p1 = head;
while (p1->next != NULL) {
p1 = p1->next;
}
p1->next = temp;
}
void Clear() { //有关数据全部初始化
sum = 0;
order = 'a'; // 给新的矩阵赋予字母编号,便于查找
while (!pt.empty()) {
pt.pop();
}
int j = 0;
p1 = head->next;
while (j < nl - 1) {
p1 = p1->next;
j++;
}
if (p1 != NULL)
p1->next = NULL;
}
/*void test() {
cout << "---------------" << endl;
p1 = head->next;
while (p1 != NULL) {
cout << p1->c << " " << p1->m << " " << p1->n << endl;
p1 = p1->next;
}
cout << "----------------" << endl;
}*/
int main() {
//freopen("D://in.txt", "r", stdin);
ios::sync_with_stdio(0);
p1 = head;
cin >> n;
nl = n;
while (n--) {
mt p2 = new struct multi();
cin >> p2->c >> p2->m >> p2->n;
p1->next = p2;
p1 = p2;
}
getchar();
string cmd;
while (getline(cin, cmd)) {
if (cmd.length() == 1) {
cout << "0" << endl;
continue;
}
else {
Clear();
//test();
for (int i = 0; i < cmd.length(); i++) {
if (cmd[i] == '(' || (cmd[i] <= 'Z' && cmd[i] >= 'A')) {
pt.push(cmd[i]);
}
else {
char c = pt.top(); pt.pop();
char c2 = pt.top(); pt.pop();
mt tmp = find(c), tmp2 = find(c2);
if (tmp2->n != tmp->m) {
cout << "error" << endl;
flag = 1;
break;
}
else {
sum += (tmp2->m) * (tmp2->n) * (tmp->n);
mt temp = new struct multi();
temp->m = tmp2->m;
temp->n = tmp->n;
order += 1;
temp->c = order;
pt.pop();
pt.push(order);
Insert(temp);
}
}
}
if (!flag) {
cout << sum << endl;
}
flag = 0;
}
}
return 0;
}
写完后再看自己的代码是很粗糙的,比如给新的矩阵赋予新的字母,如果给出的表达式过长使得ASCll码超过了255该怎么办,还有每次给新的矩阵开辟新的空间插入链表中,计算下一个表达式的时候这些空间没有释放,还存留着,造成内存泄漏,是个很不好的习惯,而刘汝佳老师的代码很精简,比我的要好多了。。。
#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
struct multi
{
int m;
int n;
multi(int a = 0, int b = 0) :m(a), n(b){}
} t[26];
stack<multi> p;
int main() {
//freopen("D://in.txt", "r", stdin);
int n;
cin >> n;
for (int i = 0; i < n; i++) {
char c;
cin >> c;
cin >> t[c - 'A'].m >> t[c - 'A'].n;
}
string expr;
while (cin >> expr) {
bool error = false;
int ans = 0;
for (int i = 0; i < expr.length(); i++) {
if (isalpha(expr[i])) {
p.push(t[expr[i] - 'A']);
}
else if (expr[i] == ')') {
multi t2 = p.top(); p.pop();
multi t1 = p.top(); p.pop();
if (t1.n != t2.m) {
error = true;
break;
}
else {
ans += t1.m * t1.n * t2.n;
p.push(multi(t1.m, t2.n));//直接创建一个multi结构体并入栈,这里第一次看过
}
}
}
if (error) {
cout << "error\n";
}
else {
cout << ans << endl;
}
}
return 0;
}