1 条题解

  • 1
    @ 2025-5-6 18:32:51

    没啥好说的上代码

    #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行
    
    • 1

    信息

    ID
    304
    时间
    1000ms
    内存
    512MiB
    难度
    8
    标签
    递交数
    23
    已通过
    6
    上传者