2017计蒜之道 初赛 第二场 百度的科学计算器(简单)
2017-05-22 11:03
387 查看
/** 题目:2017计蒜之道初赛第二场百度的科学计算器(简单) 链接:https://nanti.jisuanke.com/t/15504 题意:给一个合法的表达式,包含加号+、减号-、括号()、数字常量,表达式中没有空格。 输入数据保证数字常量以及计算过程中数值绝对值均不超过10^12,对于浮点型数值常量,保证小数点后不超过6位。 思路:暴力模拟;python有函数可以直接调用。 坑点:如果表达式中出现过浮点数,那么输出结果保留6位小数, 否则输出整数,不出现小数。 */ #include<iostream> #include<cstdio> #include<vector> #include<cstring> #include<cmath> #include<algorithm> usingnamespacestd; typedeflonglongLL; constintmod=1e9+7; constintmaxn=1e6+5; constdoubleeps=1e-12; charop[1005]; doublea[1004]; chars[1004]; intn; intflag; intmain() { while(scanf("%d",&n)==1) { scanf("%s",s); flag=0; intaz=0,pz=0; intlen=strlen(s); for(inti=0;i<len;){ LLin=0; LLdt=0; LLp=1; if(s[i]>='0'&&s[i]<='9'){ while(i<len&&s[i]>='0'&&s[i]<='9'){ in=in*10+(s[i]-'0'); i++; } if(s[i]=='.'){ flag=1; i++; while(i<len&&s[i]>='0'&&s[i]<='9'){ dt=dt*10+(s[i]-'0'); i++; p*=10; } } doublex=in+1.0*dt/p; a[az++]=x; }else { if(s[i]=='-'){ op[pz++]='-'; i++; continue; } if(s[i]=='+'){ i++; op[pz++]='+'; continue; } if(s[i]=='('){ i++; op[pz++]='('; continue; } if(s[i]==')'){///左结合。找到左边的符号,以及左边的数,然后模拟计算过去。 intpl=pz-1; while(op[pl]!='(')pl--; inttemp=pl;//pz=tmep; intcnt=pz-pl-1; inttempa=az-cnt-1; doublevalue=a[az-cnt-1]; for(intj=pl+1,k=az-cnt;j<pz;j++,k++){ if(op[j]=='+'){ value+=a[k]; }elsevalue-=a[k]; } pz=temp; az=tempa; a[az++]=value; i++; continue; } } } doublevalue=a[0];///已处理所有括号,只有数和-,+符号。左结合计算。 for(intj=0,k=1;j<pz;j++,k++){ if(op[j]=='+'){ value+=a[k]; }elsevalue-=a[k]; } if(flag)///如果出现过浮点数。 printf("%.6lf\n",value); else printf("%lld\n",(LL)value); } return0; } 表达式树解法:可处理加减乘除都出现的情况。 思路:每次把最后进行的计算符号作为根。递归处理。
#include<iostream> #include<cstdio> #include<vector> #include<cstring> #include<cmath> #include<algorithm> usingnamespacestd; typedeflonglongLL; constintmod=1e9+7; constintmaxn=1e3+5; constdoubleeps=1e-12; intlch[maxn],rch[maxn]; structnode { doublevalue; charop; }t[maxn]; intnc=0; chars[maxn]; intisDouble; intbuild_tree(char*s,intx,inty)///[x,y) { intc1=-1,c2=-1,p=0; intu; intsign=0; for(inti=x;i<y;i++){ switch(s[i]){ case'(':p++;sign=1;break; case')':p--;sign=1;break; case'+':case'-':if(!p)c1=i;sign=1;break;///括号外的最后计算的+,-符号。 case'*':case'/':if(!p)c2=i;sign=1;break;///括号外的最后计算的*,/符号。 } } if(sign==0){///全是数字或者小数点。说明已经是叶子了。 doublein=0; LLdt=0; LLp=1; while(x<y&&s[x]!='.'){ in=in*10+(s[x]-'0'); x++; } if(x<y&&s[x]=='.'){ x++; isDouble=1; while(x<y){ dt=dt*10+(s[x]-'0'); x++; p=p*10; } } u=++nc; t[u].value=in+1.0*dt/p; lch[u]=0; rch[u]=0; returnu; } if(c1<0)c1=c2;///没有加减符号. if(c1<0)returnbuild_tree(s,x+1,y-1);///没有乘除符号,那么应该是被括号包含,去掉两边的括号。 u=++nc; lch[u]=build_tree(s,x,c1); rch[u]=build_tree(s,c1+1,y); t[u].op=s[c1]; returnu; } doubledfs(introot) { if(lch[root]==0&&rch[root]==0){ returnt[root].value; } charop=t[root].op; doublelans=dfs(lch[root]),rans=dfs(rch[root]); switch(op){ case'+':returnlans+rans; case'-':returnlans-rans; case'*':returnlans*rans; case'/':returnlans/rans; } return-1; } intmain() { intn; while(scanf("%d",&n)==1) { scanf("%s",s); nc=0; isDouble=0; introot=build_tree(s,0,strlen(s));///root=1 doubleans=dfs(root); if(isDouble)printf("%.6lf\n",ans);///出现浮点数,输出6位小数,否则输出整数。 elseprintf("%lld\n",LL(ans)); } return0; }
相关文章推荐
- 2017 计蒜之道 初赛 第二场 B.百度的科学计算器(简单)
- 2017 计蒜之道 初赛 第二场 B.百度的科学计算器(简单)
- 2017 计蒜之道 初赛 第二场 B.百度的科学计算器(简单)
- 2017 计蒜之道 初赛 第二场 B.百度的科学计算器(简单)
- 2017 计蒜之道 初赛 第二场 B.百度的科学计算器(简单)
- 2017 计蒜之道 初赛 第二场 百度的科学计算器(简单)
- 2017 计蒜之道 初赛 第二场 B.百度的科学计算器(简单)
- 2017 计蒜之道 初赛 第二场 B.百度的科学计算器(简单)
- 2017 计蒜之道 初赛 第二场 B. 百度的科学计算器(简单)
- 2017 计蒜之道 初赛 第二场 B.百度的科学计算器(简单)
- 2017 计蒜之道 初赛 第二场 B.百度的科学计算器(简单)
- 2017 计蒜之道 初赛 第二场 B.百度的科学计算器(简单)
- 2017 计蒜之道 初赛 第二场 B.百度的科学计算器(简单)
- 2017 计蒜之道 初赛 第二场 B.百度的科学计算器(简单)
- 2017 计蒜之道 初赛 第二场 B.百度的科学计算器(简单)
- 2017计蒜之道初赛_百度的科学计算器(简单难度)
- 2017计蒜之道初赛第二场-百度的年会游戏
- 2017 计蒜之道 初赛 第二场 A题(百度的年会游戏)
- 计蒜客 2017 初赛第一场 B. 阿里天池的新任务(简单)
- 计蒜客 2017 初赛第一场 B. 阿里天池的新任务(简单)