UVa442矩阵链乘

The second part of the input file strictly adheres to the following syntax (given in EBNF)

输入格式是合法的,所以不用检查括号是否匹配,而且一个括号内必定有且只有两个矩阵。

因此遇到右括号就弹出两个矩阵运算。

问题是如何设计栈里面的每个元素。要做运算就要知道两个矩阵的行和列,如果弹出来的两个矩阵,列和行不匹配,输出error。如果匹配,就计算乘法次数再累加到总的次数里面。

因此栈里面的每个元素要保持行和列的维度信息。所以自然而然地就能想到用一个结构体表示每个矩阵。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
typedef struct Matrix{
	int r;
	int c;
	Matrix() {
		r = 0;
		c = 0;
	} 
	Matrix(int r, int c) {
		this->r = r;
		this->c = c; 
	}
}Matrix;
Matrix standard_26[30]; // 基本矩阵维度信息 
Matrix stack[1010];
int top = -1;
void Push(Matrix m) {
	top++;
	stack[top] = m;
	return;
}

Matrix Pop() {
	Matrix m = stack[top];
	top--;
	return m;
}


int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		char alpha[10] = {0};
		int row = 0, col = 0;
		scanf("%s%d%d", alpha, &row, &col);
		standard_26[alpha[0]-'A'].r = row;
		standard_26[alpha[0]-'A'].c = col;
	}
	char temp[1010] = {0};
	while (fgets(temp, 1010, stdin) != NULL) {
		top = -1; // 清空栈 
		if (temp[strlen(temp) - 1] == '\n') {
			temp[strlen(temp) - 1] = 0;
		}
		if (temp[0] == '\n' || temp[0] == '\0') {
			continue;
		}
		if (strlen(temp) == 1) { // 只有一个字母 
			printf("0\n");
			continue;
		}
		int error = 0;
		int sum_times = 0;
		for (int i = 0; i < strlen(temp); i++) {
			if (temp[i] == '(') {
				continue;
			} else if (temp[i] == ')') {
				if (top == -1) { // 栈空 
					break;
				}
				Matrix right = Pop();
				Matrix left = Pop();
				if (right.r != left.c) {
					error = 1;
					break;
				}
				sum_times += (left.r * left.c * right.c); 
				Push(Matrix(left.r, right.c));
			} else {
				Push(standard_26[temp[i]-'A']); 
			}
		}
		if (error == 1) {
			printf("error\n");
		} else {
			printf("%d\n", sum_times);
		}
	}
	
	return 0;
}
posted @ 2021-02-07 11:08  Mo_hw  阅读(52)  评论(0编辑  收藏  举报