1 条题解
-
10
- 我们可以使用一个结构体,结构体内用三个变量,维护三个值 (数值,与短路次数,或短路次数)
- 根据一棵表达式树的样子,若当前节点是
&
, 左儿子值为 ,则发生&
短路,对于此时节点与短路的次数在左儿子与短路次数基础上加 ,或短路的次数继承左儿子或的次数,|
的短路继承同理 - 若不发生短路,
&
短路的次数就等于左右儿子&
短路次数和,|
同理
以样例 为例,每个节点三个值分别为该节点的数值,与短路次数和或短路次数。
#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
信息
- ID
- 2037
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 4
- 标签
- 递交数
- 176
- 已通过
- 79
- 上传者