2 条题解

  • 3
    @ 2022-10-12 21:23:40

    题解

    这道题可以说是有点难度,我们先来分析一波。

    这道题的输入很明显是中缀表达式,我们程序对逆波兰表达式算起来得心应手,可是对于中缀就没有什么办法了(至少直接算来),我们可以构造树将其转换为后缀的逆波兰,我懒得写

    所以我们观察中缀表达式,考虑一下三年级数学讲的带符号搬家,我们发现,除了最开始一个数字,其他数都带有一个操作符。这样我们可以输入第一个数,然后输入操作符和数字。最后用栈模拟。

    #include <bits/stdc++.h>
    using namespace std;
    int x, ans;
    char c;
    stack<int> s;
    const int mod = 10000;
    int main()
    {
        scanf("%d", &x);
        s.push(x); // 压入最开始的数字
        while (c = getchar()) // getchar
        {
            if (c == '\n') break; // 如果读了个换行符,表示没数了
            scanf("%d", &x); // 否则输入数字
            if (c == '+')
            {
    
            }
            if (c == '*')
            {
    
            }
        }
        printf("%d\n", );
        return 0;
    }
    

    很简单吧。一点也不简单

    其实我们也可以输入整个字符串,再分解。

    这里我们注意乘法运算级更高,需要优先。但是我们计算 1+231+2*3 时,1+21+2 会被先计算,导致得不到正确结果。我们可以把加法直接压进栈,不用操作,乘法即时操作,算完压回栈。只要最后加一遍所有数字就可以了,我们模拟一下。

    11,把 11 压进去。

    +2+2,把 22 压进去。

    3*3,把 22 取出,把 23=62*3=6 压进去。

    遍历栈:1+6=71+6=7,正确。

    #include <bits/stdc++.h>
    using namespace std;
    int x, ans;
    char c;
    stack<int> s;
    const int mod = 10000;
    int main()
    {
        scanf("%d", &x);
        s.push(x); // 单独输入
        while (c = getchar())
        {
            if (c == '\n') break;
            scanf("%d", &x);
            if (c == '+')
            {
                s.push(x); // 先压入
            }
            if (c == '*')
            {
                ans = s.top() * x % mod; // 立即计算
                s.pop();
                s.push(ans);
            }
        }
        ans = 0;
        while (!s.empty())
        {
            ans = (ans + s.top()) % mod; // 计算总和,别忘了取模。
            s.pop();
        }
        printf("%d\n", ans);
        return 0;
    }
    

    ACAC CodeCode

    #include <bits/stdc++.h>
    using namespace std;
    int x, ans;
    char c;
    stack<int> s;
    const int mod = 10000;
    int main()
    {
        scanf("%d", &x);
        s.push(x);
        while (c = getchar())
        {
            if (c == '\n') break;
            scanf("%d", &x);
            if (c == '+')
            {
                s.push(x);
            }
            if (c == '*')
            {
                ans = s.top() * x % mod;
                s.pop();
                s.push(ans);
            }
        }
        ans = 0;
        while (!s.empty())
        {
            ans = (ans + s.top()) % mod;
            s.pop();
        }
        printf("%d\n", ans);
        return 0;
    }
    
    • 1
      @ 2022-9-3 0:30:18

      建议用栈模拟,先循环外单独读入一次数字压入栈中,然后后面的输入肯定是一个操作符加一个数字,然后就很好处理了,不建议把整个字符串读入以后处理。

      int x;
      char op;
      cin >> x;
      q.push(x % mod);
      while (cin >> op >> x)
      {
            if (op == "*")
             乘法的时候栈顶和次顶乘起来压入栈中
            else
          加法不操作了,最后栈里元素单独加一次即可
      }
      
      最后栈里元素全部加起来注意取模即可
      
      • @ 2022-9-3 0:30:55

        全部读入字符串以后处理也可以,就是有点麻烦。不是很建议,除非你很细心

    • 1

    [普及][NOIP2013 普及组] 表达式求值

    信息

    ID
    1426
    时间
    1000ms
    内存
    256MiB
    难度
    4
    标签
    递交数
    145
    已通过
    62
    上传者