【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();
    }
}

如果對您有幫助,記得點個贊哦~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章