传送门:https://nanti.jisuanke.com/t/31443
题意:
给出一个表达式,求最小值和最大值。
表达式中的运算符只有'+'、'-'、'*'、'd',xdy 表示一个 y 面的骰子 roll x 次的和,其中x>=0,y>=1,实际上它的最小值就是x,小于0时要强制变为0,最大值就是 x*y ,题目给的表达式保证运算都是合法的,并且中间过程和结果都是int范围内。
思路:
和正常的'+'、'-'、'*'、'/'做法基本完全一样,设一个优先级'+'、'-'为1,'*'为2,'d'为3。
先将中序表达式转为后序表达式,然后始终维护最大值和最小值就可以了。
比赛时忘了后序表达式锤了一万年都没过。。。
中序表达式->后序表达式(左->右):
数字:直接输出
运算符:将栈中所有优先级>=自己的运算符输出,之后入栈(栈为空就直接入栈)
(:入栈
):将之前所有运算符输出,直到遇到 '(' ,并且将 '('也输出
最后将栈中所有东西按顺序输出
后续表达式计算(左->右):
数字:入栈
运算符:取栈顶两个数字计算,结果入栈
遍历完后栈顶元素就是答案
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<ctime>
#include<functional>
#include<bitset>
#define P pair<int,int>
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs id*2+1
#define Mod(a,b) a<b?a:a%b+b
using namespace std;
const ll M = 998244353;
const ll INF = 1e9 + 10;
const int N = 4010;
const double e = 10e-6;
const int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
const int _dx[8] = { -1,-1,-1,0,0,1,1,1 }, _dy[8] = { -1,0,1,-1,1,-1,0,1 };
int x, y;
struct node
{
int type; //0:num 1:op
int num;
char op;
};
map<char, int> mp;
int n, m, k, l, r;
char str[110];
stack<char> s; queue<node> que;
void postfix()
{
int len = strlen(str);
for (int i = 0; i < len; i++) {
if (str[i] >= '0'&&str[i] <= '9') {
int num = 0;
while (i <= len&&str[i] >= '0'&&str[i] <= '9') {
num *= 10;
num += 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['+'] = 1; mp['-'] = 1; 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;
}