1. 程式人生 > >uva442-矩陣鏈乘

uva442-矩陣鏈乘

Your job is to write a program that determines the number of elementary multiplications needed for a given evaluation strategy.

Input Specification

Input consists of two parts: a list of matrices and a list of expressions.

The first line of the input file contains one integer n ( tex2html_wrap_inline28 ), representing the number of matrices in the first part. The next n

 lines each contain one capital letter, specifying the name of the matrix, and two integers, specifying the number of rows and columns of the matrix.

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

SecondPart = Line { Line } <EOF>
Line       = Expression <CR>
Expression = Matrix | "(" Expression Expression ")"
Matrix     = "A" | "B" | "C" | ... | "X" | "Y" | "Z"

Output Specification

For each expression found in the second part of the input file, print one line containing the word "error" if evaluation of the expression leads to an error due to non-matching matrices. Otherwise print one line containing the number of elementary multiplications needed to evaluate the expression in the way specified by the parentheses.

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
這個題讀懂題意其實還是挺簡單的,不過我卻做了一天,苦苦糾結於怎麼來區分括號的優先順序,後面看了提示知道用棧了,但還是糾結具體怎麼區分,後面又看了遍別人解題報告,我才意識到自己在審題上想當然了,這裡也算一個坑吧,題目中每個矩陣相乘就應該有一個括號,而不會存在(A*B*C)這樣的情況,開始我一直在糾結這個,按題目的意思這種形式的正確表述是((A*B)*C),這樣就方便太多了,不管左邊括號,把字母壓入棧,然後讀到右邊括號時把棧頂前兩位算下一乘積又壓入棧就好,這個題目就是考察棧的應用。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<stack>
#include<cctype>
#define LOCAL
using namespace std;

struct Node{
    int r;
    int c;
}node[30],node1[30];
int main(){
    #ifdef LOCAL
        freopen("input.txt","r",stdin);
        freopen("output.txt","w",stdout);
    #endif
    int n;
    char ch,s[100];
    scanf("%d",&n);
    getchar();
    for(int i=0;i<n;i++){
       scanf("%c",&ch);
       scanf("%d%d",&node[ch-'A'].r,&node[ch-'A'].c);
       getchar();
    }
    while(scanf("%s",s)==1){
        memcpy(node1,node,sizeof(node));
        if(strlen(s)==1){ printf("0\n");continue;}
        int row=0,col=0,flag=0;
        for(int i=0;i<strlen(s);i++)if(isalpha(s[i])){
            if(row==0&&col==0){row=node[s[i]-'A'].r;col=node[s[i]-'A'].c;}
            else if(col!=node[s[i]-'A'].r){flag=1;break;}
            col=node[s[i]-'A'].c;
        }
        if(flag==1)printf("error\n");
        else{
            stack <int> m;
            int sum=0; 
            for(int i=0;i<strlen(s);i++){
                if(isalpha(s[i]))m.push(s[i]-'A');
                else if(s[i]==')'){
                    row=node1[m.top()].r;
                    col=node1[m.top()].c;
                    m.pop();
                    sum+=node1[m.top()].r*row*col;
                    node1[m.top()].c=col;
                }
            }
            printf("%d\n",sum);
        }
    }
    return 0;
}