1 条题解
-
1
没啥好说的上代码#include <bits/stdc++.h> using namespace std; const int N = 1e6 + 10; struct node { char c;//存储结点的运算符 & | int l,r;//左右孩子的编号 int v;//结点的值 } a[N]; stack<char> op;//存储运算符,辅助中缀转后缀的过程 stack<int> st;//存储运算数,辅助后缀表达式计算的过程 char s[N];//存储中缀表达式 vector<char> v;//存储后缀表达式 int k = 0;//表示结点编号 int c1,c2;//&短路的次数, |短路的次数 //搜索求出短路的次数 void dfs(int x){ if(a[x].l == 0 && a[x].r == 0) return;//叶子结点 int t1 = a[x].l,t2 = a[x].r; dfs(t1);//搜索左孩子 //左孩子搜到底返回的过程中判断短路的次数 if(a[x].c == '&' && a[t1].v == 0){ c1++; return; } if(a[x].c == '|' && a[t1].v == 1){ c2++; return; } dfs(t2); } int main(){ freopen("expr.in", "r", stdin); freopen("expr.out","w",stdout); scanf("%s",s+1); int len = strlen(s+1); //1. 将中缀表达式转换为后缀表达式 for(int i = 1; i <= len; i++){ //如果是运算数 if(isdigit(s[i])) v.push_back(s[i]); else if(s[i] == '(') op.push(s[i]); else if(s[i] == ')'){ //弹出元素,直到遇到左括号 while(!op.empty() && op.top() != '('){ v.push_back(op.top()); op.pop(); } //左括号也要单独弹出 op.pop(); }else if(s[i] == '&'){ //弹出元素直到遇到更低优先级的运算符或者( while(!op.empty() && op.top() == '&') { v.push_back(op.top()); op.pop(); } op.push(s[i]);//将&入栈 }else{ //| while(!op.empty()&&(op.top()=='&'||op.top()=='|')){ v.push_back(op.top()); op.pop(); } op.push(s[i]);//将|入栈 } } //如果栈中还有元素,依次弹出 while(!op.empty()){ v.push_back(op.top()); op.pop(); } //2. 后缀表达式计算, 通过计算的过程建树 len = v.size(); int x,y; for(int i = 0;i < len;i++){ //如果遇到运算数, 入栈,遇到运算符,取出次顶和栈顶运算,结果入栈 if(isdigit(v[i])){ a[++k] = {0,0,0,v[i] - '0'}; st.push(k); }else{ x = st.top();//栈顶 st.pop(); y = st.top();//次顶 st.pop(); if(v[i] == '&'){ a[++k] = {v[i],y,x,a[y].v & a[x].v}; st.push(k); }else{ a[++k] = {v[i],y,x,a[y].v | a[x].v}; st.push(k); } } } cout<<a[k].v<<endl;//表达式的值 dfs(k); cout<<c1<<" "<<c2; fclose(stdin); fclose(stdout); return 0; }//满打满算100行
信息
- ID
- 304
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 8
- 标签
- 递交数
- 23
- 已通过
- 6
- 上传者