1 条题解

  • 10
    @ 2023-9-28 21:52:10
    • 我们可以使用一个结构体,结构体内用三个变量,维护三个值 (数值,与短路次数,或短路次数)
    • 根据一棵表达式树的样子,若当前节点是 &, 左儿子值为 00,则发生 & 短路,对于此时节点与短路的次数在左儿子与短路次数基础上加 11,或短路的次数继承左儿子或的次数, | 的短路继承同理
    • 若不发生短路,& 短路的次数就等于左右儿子 & 短路次数和,| 同理

    以样例 11 为例,每个节点三个值分别为该节点的数值,与短路次数和或短路次数。

    image

    #include <bits/stdc++.h>
    #define ll long long
    #define x first
    #define y second
    using namespace std;
    typedef pair<int, pair<int, int>> p;
    string s;
    map<char, int> mp;
    stack<p> st;
    stack<char> op;
    void eval()
    {
        auto a = st.top(); // 右儿子
        st.pop();
        auto b = st.top(); // 左儿子
        st.pop();
        char c = op.top();
        op.pop();
        if (c == '&')
        {
            if (b.x == 0) // 左儿子值为 0 发生 & 短路 ,
            {
                p now = {a.x & b.x, {b.y.x + 1, b.y.y}}; // 发生短路不会去右儿子,只继承左儿子答案
                st.push(now);
            }
            else
            {
                p now = {a.x & b.x, {a.y.x + b.y.x, a.y.y + b.y.y}};// 不短路,答案继承左右儿子的次数和
                st.push(now);
            }
        }
        if (c == '|')
        {
            if (b.x == 1) // 左儿子值为 1 发生 | 短路 ,
            {
                p now = {a.x | b.x, {b.y.x, b.y.y + 1}}; // 发生短路不会去右儿子,只继承左儿子答案
                st.push(now);
            }
            else
            {
                p now = {a.x | b.x, {a.y.x + b.y.x, a.y.y + b.y.y}};// 不短路,答案继承左右儿子的次数和
                st.push(now);
            }
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> s;
        mp['&'] = 2, mp['|'] = 1;
        for (auto c : s)
        {
            if (isdigit(c))
            {
                st.push({c - '0', {0, 0}});
            }
            else if (c == '(') op.push('(');
            else if (c == ')')
            {
                while (op.size() && op.top() != '(') eval();
                op.pop();
            }
            else
            {
                while (op.size() && mp[op.top()] >= mp[c]) eval();
                op.push(c);
            }
        } 
        while (op.size()) eval();
        cout << st.top().x << "\n" << st.top().y.x << " " << st.top().y.y;
        return 0;
    }
    
    • 1

    [CSP-J 2022] 逻辑表达式(expr)

    信息

    ID
    2037
    时间
    1000ms
    内存
    256MiB
    难度
    4
    标签
    递交数
    176
    已通过
    79
    上传者