最大最小



题目:


分析:

众所周知,在一个只有加法和乘法的算式里,如果可以任意加括号,那么结果最大就是先算加法再算乘法,最小就是先算乘法再算加法。那么,这道题就很简单了。我们可以用两个栈maxs和mins分别用来计算最大值和最小值,再有两个变量maxres和minres,分别表示最大值和最小值。由于数据较大,所以数的类型应该为__int64,并且要对870764322取膜,为了方便,我们把870764322设为符号常量N。接下来只要牢记最大值是先算加法,最小值是先算乘法就好了。我们可以从左往右遍历一遍字符串,如果遇到数字,就将该数字分别放进maxs和mins。如果遇到‘+’,即str[i]'+',这时maxs和mins要兵分两路,最小值要先算乘法,加法先不算,所以mins直接进栈‘+’的下一个元素(即str[++i])就行,而最大值要先算加法,所以要把maxs栈顶元素和str[i]相加(注意,由于前面已经++i,所以这时的str[i]就是‘+’的下一个元素)。同理,当遇到str[i]‘*’时,maxs直接进栈元素str[++i],mins的栈顶元素和str[i]相乘。最后把maxs里的所有元素相乘即为最大值,把mins里的所有元素相加即为最小值。下面通过一个例子来具体说明。

例如:输入 1 + 2 * 3 + 4 * 5

  1. str[0]==' 1 ' , 直接进栈,maxs={1} , mins={1}
  2. str[1]' + ' , str[++i]' 2 ' , maxs={3}(1+2=3,栈顶为3) , mins={1,2}(2直接进栈,栈顶为2)
  3. str[3]' * ' , str[++i]' 3 ' , maxs={3,3}(3直接进栈,栈顶为3) , mins={1,6}(2 * 3=6,栈顶为6)
  4. str[5]' + ' , str[++i]' 4 ' , maxs={3,7}(3+4=7,栈顶为7) , mins={1,6,4}(4直接进栈,栈顶为4)
  5. str[7]' * ' , str[++i]' 5 ' , maxs={3,7,5}(5直接进栈) , mins={1,6,20}(4 * 5=20,栈顶为20)
  6. 遍历完成,maxres = 3 * 7 * 5 = 105 , minres = 1 + 6 + 20 = 27
    (PS:此处只是对过程进行演示,对N取膜等细节处理并未体现,大家自己注意)

代码:

#include<iostream>
#include<stack>
#include<string>
using namespace std;
#define N 870764322                                         //设置符号常量N

int main()
{
    int i, n;
    __int64 res;
    string str;
    stack<__int64>maxs;
    stack<__int64>mins;

    cin >> str;
    n = str.size();
    
    for (i = 0; i<n; i++)
    {
        if ('0'<str[i] && str[i] <= '9')                     //遇到数字 
        {
            maxs.push(str[i] - '0');                        //直接进栈 
            mins.push(str[i] - '0');
        }
        
        else if (str[i] == '+')                             //遇到“+” 
        {
            mins.push(str[++i]-'0');                  	   //'+'的下个数直接进栈,最后再算(最小值) 
            res=(maxs.top()+(str[i]-'0'))%N;               //先算加法 (最大值) 
            maxs.pop();
            maxs.push(res);
        }
        
        else                                               //遇到“*” 
        {
            maxs.push(str[++i]-'0');                      //'*'的下个数直接进栈,最后再算(最大值) 
            res=(mins.top()*(str[i]-'0'))%N;              //先算乘法(最小值) 
            mins.pop();
            mins.push(res);
        }
    }

    __int64 maxres=1,minres=0;
    
    while(!maxs.empty())                                 //再算乘法(最大值) 
    {
        maxres*=maxs.top();
        maxres%=N;
        maxs.pop();
    }
    
    while(!mins.empty())                                 //再算加法(最小值) 
    {
        minres+=mins.top();
        minres%=N;
        mins.pop();
    }
    
    printf("%I64d
%I64d
",maxres,minres);
    
    return 0;
}


原文地址:https://www.cnblogs.com/jiuweilinghu/p/5978560.html