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