CSP-J 2022 逻辑表达式
又一次被算术表达式崩了,每次遇到相似的题每次不订正,留下惨痛的教训。
思维的养成比单纯理解更重要。
以后看到表达式就要往树上想
表达式存在优先级不好计算,所以想办法使之可以顺序运算,用 后缀表达式 可以实现这一点。
然后将每个数字赋予一个三元组即三个答案,按照后缀表达式,每次碰到符号后将栈顶的两个元素合并,最后剩下的那个元素即是答案。
转移如下:
if(q.front()=='&'){
if(A.v==0) Q.push((qh){0,A.a+1,A.b});
else Q.push((qh){B.v,A.a+B.a,A.b+B.b});
}
else{
if(A.v==1) Q.push((qh){1,A.a,A.b+1});
else Q.push((qh){B.v,A.a+B.a,A.b+B.b});
}
#include<cstdio>
#include<iostream>
#include<cstring>
#include<stack>
#include<queue>
using namespace std;
const int N=1e6+5;
int n;
char s[N];
struct qh{int v,a,b;};
queue<char> q;
stack<qh> Q;
stack<char> in;
int prio(char a){
if(a=='(') return 0;
if(a=='|') return 1;
if(a=='&') return 2;
}
void Back(){
for(int i=1;i<=n;i++){
if(s[i]=='1'||s[i]=='0') q.push(s[i]);
if(s[i]=='&'||s[i]=='|'){
while (in.size()){
if(prio(s[i])<=prio(in.top())) q.push(in.top()),in.pop();
else break;
}
in.push(s[i]);
}
if(s[i]=='(') in.push(s[i]);
else if(s[i]==')'){
while (in.size()){
if(in.top()!='(') q.push(in.top()),in.pop();
else break;
}
in.pop();
}
}
while (in.size()) q.push(in.top()),in.pop();
return ;
}
int main(){
scanf("%s",s+1);
n=strlen(s+1);
Back();
while (q.size()){
if(q.front()=='0'||q.front()=='1') Q.push((qh){q.front()-'0',0,0});
else{
qh B=Q.top();Q.pop();
qh A=Q.top();Q.pop();
if(q.front()=='&'){
if(A.v==0) Q.push((qh){0,A.a+1,A.b});
else Q.push((qh){B.v,A.a+B.a,A.b+B.b});
}
else{
if(A.v==1) Q.push((qh){1,A.a,A.b+1});
else Q.push((qh){B.v,A.a+B.a,A.b+B.b});
}
}
q.pop();
}
printf("%d\n%d %d",Q.top().v,Q.top().a,Q.top().b);
return 0;
}
/*
start coding:16:49
finish debuging:17:43
*/