• [1041] XX easy problem


    [题目传送] http://djks.nbut.edu.cn:8090/JudgeOnline/problem.php?id=1041

    [思路] 运用小学生的直觉,我们只能加一个括号,那么这个括号加的位置肯定要将“和”最大的一边,和乘法相结合,才可能有更好的结果。

    例如:

    原式:1+2+3*4+3*9

    我们应该觉得括号加在这几个位置需要考虑就行:

    (1+2+3)*4+3*9

    (1+2+3*4+3)*9

    1+2+3*(4+3)*9

    1+2+3*(4+3*9)

    加在其他位置并不能影响结果,所以观察发现,其实我们只要盯住乘号,就能枚举所有情况。

    好的,以上是小学生思路,来讲讲大学生思路,既然这题长度最多50,数字1-9。那我们把每个可能的位置都加一遍,看看哪种比较好不就好了么!(才50的长度,不会超时的)

    这里处理算式可以用两个数组,和一个栈来处理讨厌的+和*的优先级问题

    我们把读进来的算式,数字和运算符号分别放在两个数组里比如上面例子 1+2+3*4+3*9

    分解成

    A[] : 1 2 3 4 3 9

    B[] : + + * + *

    然后我们用一个数组模拟栈,比如它叫做 S[]

    进行以下操作:

    1.把A[0] 元素压进栈,S[0] = A[0];

    2.循环B数组,如果B[i] 是 + 号,将 A[i+1] 加进S[] 数组中,如果是*号,将S[]数组的最后一个元素取出,乘上A[i + 1] 再压回去到S[] 的末尾。

    经过这样的处理后S[]变成了 S[] : 1 2 12 27

    把S[] 数组求个和就是原式的值啦~! 

    接下来用两个套嵌的for循环来枚举所有的括号出现的位置,左括号,右括号。

    我们约定,l , r 分别是两个括号的位置,表示左括号出现在下标为l的数的左边,有括号出现在下标为r的数的右边。

    计算括号加在l ,r位置的函数叫做Get(l,r);

    我们可以先Get(0,0) 让表达式的值按不加括号的顺序先计算初始值。 

    Get(0,0) 等同于(1)+2+3*4+3*9 可以看出来相当于没有加上括号。接下来的任务基本就是枚举l r的位置,然后计算Get就行,既然前面计算过不加括号的值作为初始值,我们枚举的时候注意 r - l >= 1这样括号就不会只扩在一个数上了。

    接下来写Get(l,r)函数,我们先计算l - r这一段被括号扩起来的算式,按照前面那种“一个栈两个数组的方式” 计算出了这个括号内的值为val。

    然后我们算整个算式的值,我们在碰到 左括号  之前,还是按照“一个栈两个数组”的方式计算值,也就是 0 - l 。

    碰到 l 时,特别判断下,将val放进去操作。  然后 l - r 位置都不进行操作。

    最后 r - 最后一个数字,仍然正常操作。

    最后把栈里的数字加起来,就得到了括号加在l r位置的算式值了,返回到主函数里,比较下,输出就行。

    [代码]

     1 #include <iostream>
     2 #include <vector>
     3 #include <stack>
     4 #include <string>
     5  
     6 using namespace std;
     7 vector<long long> num;
     8 vector<char> oper;
     9  
    10 void init(){
    11     num.clear(); oper.clear();
    12     return ;
    13 }
    14  
    15 void check(){
    16     for(int i = 0 ; i < num.size() ; i++) cout << num[i] << " " ; cout << endl;
    17     for(int i = 0 ; i < oper.size() ; i++) cout << oper[i] << " "; cout << endl;
    18     return ;
    19 }
    20  
    21 long long Get(int l , int r){
    22     stack<long long> in;
    23     for(int i = l ; i <= r ; i++){
    24         if(i == l) in.push(num[i]);
    25         else{
    26             if(oper[i - 1] == '+') in.push(num[i]);
    27             else{
    28                 long long temp = in.top();
    29                 in.pop();
    30                 in.push(temp * num[i]);
    31             }
    32         }
    33     }
    34     long long val = 0;
    35     while(!in.empty()){
    36         val += in.top(); in.pop();
    37     }
    38     /////////////////
    39     vector<long long> temp_num;
    40     vector<char> temp_op;
    41     for(int i = 0 ; i < num.size() ; i++){
    42         if(i == l){temp_num.push_back(val); continue;}
    43         if(i >= l && i <= r) continue;
    44         temp_num.push_back(num[i]);
    45     }
    46     for(int i = 0 ; i < oper.size() ; i++){
    47         if(i >= l && i < r) continue;
    48         temp_op.push_back(oper[i]);
    49     }
    50     ///check
    51     //cout << "IN " << l << " " << r << endl;
    52     //for(int i = 0 ; i < temp_num.size() ; i++) cout << temp_num[i] << " "; cout << endl;
    53     //for(int i = 0 ; i < temp_op.size() ; i++) cout << temp_op[i] << " "; cout << endl;
    54     ////
    55     long long ans = 0;
    56     in.push(temp_num[0]);
    57     for(int i = 0 ; i < temp_op.size() ; i++){
    58         if(temp_op[i] == '+') in.push(temp_num[i + 1]);
    59         else{
    60             long long temp = in.top(); in.pop();
    61             in.push(temp * temp_num[i + 1]);
    62         }
    63     }
    64     while(!in.empty()){
    65         ans += in.top();
    66         in.pop();
    67     }
    68     //cout << "OUT " << ans << endl;
    69     return ans;
    70 }
    71 int main(){
    72     string in;
    73     while(cin >> in){
    74         init();
    75         int size = in.size();
    76         for(int i = 0 ; i < size ; i++){
    77             if(i%2 == 0) num.push_back(in[i] - '0');
    78             else oper.push_back(in[i]);
    79         }
    80         long long ans = Get(0,0);
    81         for(int i = 0 ; i < num.size() - 1 ; i++){
    82             for(int j = i + 1 ; j < num.size() ; j++){
    83                 ans = max(ans , Get(i,j));
    84             }
    85         }
    86         cout << ans << endl;
    87     }
    88     return 0;
    89 }
  • 相关阅读:
    提纲挈领webrtc之vad检测
    提纲挈领webrtc音频处理算法之写在前面的话
    搭建git远程服务器三步骤
    详解m4文件
    chrome浏览器被reimage pair 劫持怎么处理
    linux查看系统32位还是64位
    git gc和fsck的用法
    ubuntu 16.04 的64位 安装arm-none-linux-gnueabi-gcc的步骤和问题解决
    利用终端命令实现进入ntfs分区有两种方法。
    ubuntu-14.10下,安装gcc交叉编译器遇到问题及解决方法
  • 原文地址:https://www.cnblogs.com/ticsmtc/p/5350815.html
Copyright © 2020-2023  润新知