ACM-ICPC 2018 瀋陽賽區網絡預賽 B Call of Accepted(表達式求值)

https://nanti.jisuanke.com/t/31443c++

題意

給出一個表達式,求最小值和最大值。git

  表達式中的運算符只有'+'、'-'、'*'、'd',xdy 表示一個 y 面的骰子 roll x 次的和,其中x>=0,y>=1,實際上它的最小值就是x,小於0時要強制變爲0,最大值就是 x*y ,題目給的表達式保證運算都是合法的,而且中間過程和結果都是int範圍內。post

分析spa

表達式求值,多了一個d運算,維護最大最小值,在乘法的時候取全部極值的狀況。code

 

中序表達式->後序表達式(左->右):blog

  數字:直接輸出get

  運算符:將棧中全部優先級>=本身的運算符輸出,以後入棧(棧爲空就直接入棧)it

  (:入棧class

  ):將以前全部運算符輸出,直到遇到 '(' ,而且將 '('也輸出遍歷

  最後將棧中全部東西按順序輸出

 

後續表達式計算(左->右):

  數字:入棧

  運算符:取棧頂兩個數字計算,結果入棧

  遍歷完後棧頂元素就是答案

#include<bits/stdc++.h>
using namespace std;
struct Node{
    int type;
    int num;
    char op;
};
map<char,int>mp;
char str[110];
stack<char> s;
queue<Node> que;
void postfix(){//中綴轉後綴
    int len = strlen(str);
    for(int i=0;i<len;i++){
        if(isdigit(str[i])){
            int num=0;
            while(i<=len&&isdigit(str[i])){
                num=num*10+str[i]-'0';
                i++;
            }
            que.push(Node{0,num,'0'});
        }
        if(i>=len) break;
        if(str[i]=='(') s.push(str[i]);
        else if(str[i]==')'){
            while(s.top()!='('){
                que.push(Node{1,0,s.top()});
                s.pop();
            }
            s.pop();
        }else{
            while(!s.empty()&&mp[s.top()]>=mp[str[i]]){
                que.push(Node{1,0,s.top()});
                s.pop();
            }
            s.push(str[i]);
        }
    }
    while(!s.empty()){
        que.push(Node{1,0,s.top()});
        s.pop();
    }
}
int main(){
    mp['+']=mp['-']=1;
    mp['/']=mp['*']=2;
    mp['d']=3;
    while(~scanf("%s",str)){
        postfix();
        stack<int> small,big;
        while(!que.empty()){//後綴計算
            Node u = que.front();que.pop();
            if(u.type==0) small.push(u.num),big.push(u.num);
            else{
                int sb = small.top(); small.pop();
                int sa = small.top(); small.pop();
                int bb = big.top(); big.pop();
                int ba = big.top(); big.pop();
                if (u.op == '+') 
                    sa += sb, ba += bb;                
                else if (u.op == '-')
                    sa -= bb, ba -= sb;
                else if (u.op == '*') {
                    int minn = min(min(sa*sb, sa*bb), min(ba*sb, ba*bb));
                    int maxx = max(max(sa*sb, sa*bb), max(ba*sb, ba*bb));
                    sa = minn; ba = maxx;
                }
                else if (u.op == 'd') {
                    if (sa < 0)sa = 0;
                    ba *= bb;
                }
                small.push(sa); big.push(ba);
            }
        }
        printf("%d %d\n", small.top(), big.top());
    }
    return 0;
}
相關文章
相關標籤/搜索