/* coder: ACboy date: 2010-3-7 result: AC description: UVa 442 Matrix Chain Multiplication */ #include <iostream> #include <algorithm> #include <map> using namespace std; struct matrix{ char name; int row; int column; }; // map容器中元素用于比较的函数对象 struct cmp{ bool operator () (const char a, const char b) { return a < b; } }; // 用于存储矩阵 matrix data[100]; // 用来存储矩阵运算表示式的栈 char stack[100]; int top; void delTheSpace(char input[], char output[]) { int len = strlen(input); int count = 0; for (int i = 0; i < len; i++) { if (input[i] != ' ') { output[count++] = input[i]; } } output[count] = '/0'; } // 检测两个矩阵是否匹配 bool match(matrix & a, matrix & b) { return a.column == b.row; } int main() { int n; #ifndef ONLINE_JUDGE freopen("442.txt", "r", stdin); #endif scanf("%d/n", &n); int i; char input[100]; map<char, int, cmp> dataMap; // 输入矩阵 for (i = 0; i < n; i++) { char name; int row; int column; gets(input); sscanf(input, "%c %d %d", &name, &row, &column); data[i].name = name; data[i].row = row; data[i].column = column; dataMap.insert(make_pair(data[i].name, i)); } int k = 97; // 计算每个表达式的值 while (gets(input)) { char temp[100]; // 去掉运算式多余的空格包括前导空格和中间的空格 delTheSpace(input, temp); top = 0; // 运算式的第一个字符进栈 stack[top++] = temp[0]; int len = strlen(temp); // 用来存储答案 int ans = 0; // 用来标记表达式是否有错 int errorFlag = 0; // 循环向栈添加运算式的一个字符 for (i = 1; i < len; i++) { errorFlag = 0; stack[top++] = temp[i]; // while循环用于计算栈顶的两个字符,直到栈顶的两个 // 字符不能进行计算(如(A) while (1) { // 取出栈顶两个字符进行检测 char a = stack[--top]; char b = stack[--top]; // 如果栈顶的两个字符都是字母(即都是矩阵) if (isalpha(a) && isalpha(b)) { int apos = dataMap[a]; int bpos = dataMap[b]; // 检测是否匹配 if (match(data[bpos], data[apos])) { ans += data[bpos].row * data[apos].column * data[bpos].column; // 新生成的矩阵放到data中 data[n].name = k++; data[n].row = data[bpos].row; data[n].column = data[apos].column; // 生成一个新的矩阵,把矩阵名和位置n插入映射容器map中 dataMap.insert(make_pair(data[n].name, n)); // 新矩阵入栈 stack[top++] = data[n].name; n++; } // 不匹配标记为运算式错误,退出循环 else { errorFlag = 1; break; } } // 如果最后只剩下一个矩阵( 例如(a) 则把a入栈即运算表达式从(a)-> a)。 else if (stack[top - 1] == '(' && isalpha(b) && a == ')') { stack[top - 1] = b; } // 如果取出的两个字符是()则继续取两个字符 else if (a == ')' && b == '('){ continue; } // 如果都不是以上的各种情况就只能把字符从新入栈。 // 即例如两个字符为(a else { stack[top++] = b; stack[top++] = a; break; } } if (errorFlag) break; } if (errorFlag) { cout << "error" << endl; } else { cout << ans << endl; } } return 0; }