zoukankan      html  css  js  c++  java
  • ACM-ICPC 2018 沈阳赛区网络预赛 B Call of Accepted(表达式求值)

    题目链接:https://nanti.jisuanke.com/t/31443
    相关前置链接
    https://www.cnblogs.com/dolphin0520/p/3708602.html
    https://zh.wikipedia.org/wiki/调度场算法
    https://zh.wikipedia.org/wiki/逆波兰表示法
    https://blog.csdn.net/f_zyj/article/details/51509958

    思路

    • 调度场算法+后缀表达式(逆波兰)求值
      • 先将中缀表达式化成后缀表达式(调度场)
      • 在对后缀表达式求值
    • 前缀和处理优先级+递归构造表达式树
      • 括号内的元素优先级较高,因此处理出来每个位置的前缀和越大的优先级越高
      • 构造表达式树本质:优先级越高越早计算,意味着越靠近递归返回边界,意味着在递归树越深的位置
      • 因此会出现十分有趣的遍历顺序,+,-,*,/,d
      • 加上-和/和d是不满足交换律的,就是前面的符号要先计算,所以倒着扫
    #include<bits/stdc++.h>
    #define se second
    #define ft first
    #define pii pair<int,int>
    #define mk make_pair
    using namespace std;
    char s[105],f[105];
    int i,n;
    pii ans;
    pii add(pii x,pii y){
    	return mk(x.ft+y.ft,x.se+y.se);
    }
    pii del(pii x,pii y){
    	return mk(x.ft-y.se,x.se-y.ft);
    }
    pii mul(pii x,pii y){
    	int a=min(x.ft*y.ft,x.ft*y.se),b=max(x.ft*y.ft,x.ft*y.se);
    	a=min(a,x.se*y.ft);b=max(b,x.se*y.ft);
    	a=min(a,x.se*y.se);b=max(b,x.se*y.se);
    	return mk(a,b);
    }
    pii D(pii x,pii y){
    	return mk(x.ft,x.se*y.se);
    }
    
    pii dfs(int l,int r){
    	int i;
    	for(i=l;i<=r;i++){
    		if(s[i]=='+'&&f[i]==f[l])
    			return add(dfs(l,i-1),dfs(i+1,r));
    	}
    	for(i=r;i>=l;i--){
    		if(s[i]=='-'&&f[i]==f[l])return del(dfs(l,i-1),dfs(i+1,r));
    	}
    	for(i=l;i<=r;i++){
    		if(s[i]=='*'&&f[i]==f[l])return mul(dfs(l,i-1),dfs(i+1,r));
    	}
    	for(i=r;i>=l;i--){
    		if(s[i]=='d'&&f[i]==f[l])return D(dfs(l,i-1),dfs(i+1,r));
    	}
    	if(s[l]=='('){
    		for(i=l+1;f[i]>=f[l+1];i++);
    		return dfs(l+1,i-1);
    	}
    	int tp=0;
    	for(i=l;i<=r;i++){
    		if(s[i]<'0'||s[i]>'9')break;
    		tp*=10;
    		tp+=s[i]-'0';
    	}
    	return mk(tp,tp);
    }
    int main(){
    	while(~scanf("%s",s)){
    		memset(f,0,sizeof(f));
    		n=strlen(s);
    		f[0]=1;
    		for(i=1;i<n;i++){
    			if(s[i-1]=='(')f[i]=f[i-1]+1;
    			else if(s[i]==')')f[i]=f[i-1]-1;
    			else f[i]=f[i-1];
    		}
    		ans=dfs(0,n-1);
    		printf("%d %d
    ",ans.ft,ans.se);
    	}
    }
    
  • 相关阅读:
    uni-app调用原生的文件系统管理器(可选取附件上传)
    uni-app图片压缩转base64位 利用递归来实现多张图片压缩
    解释器模式
    外观模型
    装饰模式
    组合模式
    原型模式
    简单工厂模式
    抽象工厂模式
    工厂方法模式
  • 原文地址:https://www.cnblogs.com/VIrtu0s0/p/9635942.html
Copyright © 2011-2022 走看看