【CCF 201903-2】 二十四点(符号栈)

写在前面

本题的常规做法是使用符号栈,特殊解法是使用Python的eval函数

算法思想

将中缀表达式转化为后缀表达式,使用符号栈数字栈

当新的符号op入栈时,有两种情况:

① op的优先级 > 符号栈栈顶符号的优先级:直接入栈

② op的优先级 ≤ 符号栈栈顶符号的优先级:

     不断地将符号栈的元素弹出至数字栈,直到op的优先级 > 符号栈栈顶符号的优先级。

     此时再将op入栈。

当表达式遍历完成时,将符号栈剩余的符号依次弹出到数字栈,最终数字栈中的元素就是运算的结果。

C++11满分代码

#include <iostream>
#include <stack>
using namespace std;

stack<int> nums;    // 数字栈
stack<char> ops;    // 符号栈

/* 获取符号的优先级 */
int priority(char op)
{
    if(op == '+' || op == '-') return 1;
    return 2;
}

/* 计算 a op b 的值 */
int calculate(char op, int a, int b)
{
    if(op == '+') return a + b;
    if(op == '-') return a - b;
    if(op == 'x') return a * b;
    return a / b;
}

int main()
{
    // 关闭同步
    ios::sync_with_stdio(false);

    int n;
    cin >> n;
    cin.get();

    while (n--)
    {
        string expr;
        getline(cin, expr);

        for (size_t i = 0; i < expr.length(); ++i)
        {
            if (i & 1) // 符号压入符号栈
            {
                // 若op的优先级更高
                if(ops.empty() || priority(ops.top()) < priority(expr[i]))
                    ops.push(expr[i]);
                else
                {
                    // 不断地弹出ops,直到op的优先级更高
                    while(!ops.empty() && priority(ops.top()) >= priority(expr[i]))
                    {
                        // ops弹出符号,数字栈弹出2个数字;它们的运算结果压入数字栈
                        int b = nums.top();
                        nums.pop();
                        int a = nums.top();
                        nums.top() = calculate(ops.top(), a, b);
                        ops.pop();
                    }
                    ops.push(expr[i]);  // 将op压入符号栈
                }
            }
            else nums.push(expr[i] - '0');    // 数字直接压入数字栈
        }

        // 弹出剩余的符号
        while(!ops.empty())
        {
            int b = nums.top();
            nums.pop();
            int a = nums.top();
            nums.top() = calculate(ops.top(), a, b);
            ops.pop();
        }

        // cout << nums.top() << "\n";
        cout << (nums.top() == 24 ? "Yes" : "No") << "\n";
        nums.pop();
    }
}

如果对您有帮助,记得点个赞哦~

发布了98 篇原创文章 · 获赞 155 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/leelitian3/article/details/104730888