ACM-ICPC 2018 沈阳赛区网络预赛 B Call of Accepted(表达式求值)

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

题意

给出一个表达式,求最小值和最大值。

  表达式中的运算符只有'+'、'-'、'*'、'd',xdy 表示一个 y 面的骰子 roll x 次的和,其中x>=0,y>=1,实际上它的最小值就是x,小于0时要强制变为0,最大值就是 x*y ,题目给的表达式保证运算都是合法的,并且中间过程和结果都是int范围内。

分析

表达式求值,多了一个d运算,维护最大最小值,在乘法的时候取所有极值的情况。

 

中序表达式->后序表达式(左->右):

  数字:直接输出

  运算符:将栈中所有优先级>=自己的运算符输出,之后入栈(栈为空就直接入栈)

  (:入栈

  ):将之前所有运算符输出,直到遇到 '(' ,并且将 '('也输出

  最后将栈中所有东西按顺序输出

 

后续表达式计算(左->右):

  数字:入栈

  运算符:取栈顶两个数字计算,结果入栈

  遍历完后栈顶元素就是答案

#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;
}

 

posted @ 2018-09-19 18:13  litos  阅读(282)  评论(0编辑  收藏  举报