这篇文章上次修改于 366 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
(题目真的长)
简化题意:在计算逻辑表达式时,会出现$1 \mathbin{|} b$ 和 $0 \mathbin{\&} b$ 的情况(也就是短路),后面的 $b$ 并不计算,需要你统计这类情况出现的次数,因为 $b$ 不用计算,所以计算$b$造成的短路不用计入最终的统计。
思路分析:如果直接将表达式转换为表达式树,为每个节点维护 $2$ 个值对应两种短路,在递归计算的时候,可以非常方便的维护出当前节点的 $2$ 个值,也就是有没有短路决定加不加 $1$,在相应的加上下面计算过程中产生的短路。
警钟长鸣:因为递归容易造成爆栈,所以可以转换为后缀表达式进行计算,即可AC。
细节处理1:中缀转成后缀表达式只用从前往后看,操作数直接加入后缀表达式序列,操作符就在栈中把优先级比他高的弹出大后缀表达式序列,再把这个运算符加入栈中,左括号直接加入栈,右括号弹栈到上一个左括号。
细节处理2:后缀表达式的计算是一个栈模拟的过程,遇到运算数直接加入,遇到运算符弹出 $2$ 个,再加入计算所得的答案。
差不多了,贴代码:
#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;
long long read(){
char temp=getchar();
long long f=1,x=0;
while('0'>temp||temp>'9'){
(temp=='-')?(f=-1):0;
temp=getchar();
}
while('0'<=temp&&temp<='9'){
x=(x<<3)+(x<<1)+(temp^'0');
temp=getchar();
}
return f*x;
}
class node{
public:
int ansa,ansb;
int i;
node(int a,int b,int j){
ansa=a;
ansb=b;
i=j;
}
node(){
ansa=ansb=i=0;
}
};
stack<node>calc;
stack<char>ex;
int nowb=0;
int ansa=0,ansb=0;
char bac[1000005];
int dfs(){
for(int i=1;i<=nowb;i++){
if(i==nowb-1){
i=nowb-1;
}
if(bac[i]=='1'||bac[i]=='0'){
calc.push(node({0,0,i}));
}else if(bac[i]=='|'){
node a=calc.top();
calc.pop();
node b=calc.top();
calc.pop();
node in;
in.i=i;
bac[i]=(((bac[a.i]-'0')||(bac[b.i]-'0'))+'0');
if(bac[b.i]=='1'){
in.ansa=b.ansa;
in.ansb=b.ansb+1;
}else{
in.ansa=a.ansa+b.ansa;
in.ansb=a.ansb+b.ansb;
}
calc.push(in);
}else{
node a=calc.top();
calc.pop();
node b=calc.top();
calc.pop();
node in;
in.i=i;
bac[i]=(((bac[a.i]-'0')&&(bac[b.i]-'0'))+'0');
if(bac[b.i]=='0'){
in.ansa=b.ansa+1;
in.ansb=b.ansb;
}else{
in.ansa=a.ansa+b.ansa;
in.ansb=a.ansb+b.ansb;
}
calc.push(in);
}
}
ansa=calc.top().ansa;
ansb=calc.top().ansb;
return bac[calc.top().i]-'0';
}
int mian(){
// freopen("expr.in","r",stdin);
// freopen("expr.out","w",stdout);
char temp=getchar();
while(temp!=EOF){
if(temp=='0'||temp=='1'){
bac[++nowb]=temp;
}else if(temp=='|'){
while(ex.size()>0&&(ex.top()=='&'||ex.top()=='|')){
bac[++nowb]=ex.top();
ex.pop();
}
ex.push('|');
}else if(temp=='&'){
while(ex.size()>0&&ex.top()=='&'){
bac[++nowb]=ex.top();
ex.pop();
}
ex.push('&');
}else if(temp=='('){
ex.push('(');
}else if(temp==')'){
while(ex.size()>0&&ex.top()!='('){
bac[++nowb]=ex.top();
ex.pop();
}
ex.pop();
}
temp=getchar();
}
while(ex.size()>0){
bac[++nowb]=ex.top();
ex.pop();
}
printf("%d\n",dfs());
printf("%d %d",ansa,ansb);
return 0;
}
欢迎到博客查看其它题解。