左括号一定在*和+之间,右括号一定在+和+乘之间。乘号最多15个所以可以暴力枚举括号位置。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
#define LL long long
using namespace std;
#define maxn 5005
char s[maxn];
int ps1[maxn];
int ps2[maxn];
LL num[maxn];
char sig[maxn];
int nn,sn;
int len;
int pri(char c){
if(c=='+'||c=='-') return 1;
if(c=='*'||c=='/') return 2;
if(c=='(') return 0;
}
void cal(){
if(sig[sn]=='+') num[nn-1]=num[nn]+num[nn-1];
if(sig[sn]=='-') num[nn-1]=num[nn-1]-num[nn];
if(sig[sn]=='*') num[nn-1]=num[nn-1]*num[nn];
if(sig[sn]=='/') num[nn-1]=num[nn-1]/num[nn];
nn--;
sn--;
}
LL solve(int l,int r){
if(r<l) return 0;
nn=sn=0;
int curn=0;
for(int i=0;i<=len;i++){
if(i==l) sig[++sn]='(';
if(isdigit(s[i])){
curn=curn*10+s[i]-'0';
}
else {
if(i-1!=r){
num[++nn]=curn;
curn=0;
}
if(sn&&pri(s[i])<=pri(sig[sn])) cal();
sig[++sn]=s[i];
}
if(i==r) {
num[++nn]=curn;
curn=0;
while(sig[sn]!='(') cal();
sn--;
}
}
if(len!=r) num[++nn]=curn;
while(nn>1) cal();
return num[1];
}
int main(){
while(~scanf("%s",s)){
int n1=0,n2=0;
len=strlen(s);
LL res=solve(0,len-1);
ps1[++n1]=0;
for(int i=1;i<len-2;i+=2){
if(s[i]=='*'&&s[i+2]=='+') ps1[++n1]=i+1;
}
for(int i=1;i<len-2;i+=2){
if(s[i]=='+'&&s[i+2]=='*') ps2[++n2]=i+1;
}
ps2[++n2]=len-1;
int clen;
for(int i=1;i<=n1;i++){
for(int j=1;j<=n2;j++){
int s=ps1[i];
int t=ps2[j];
if(s>t) continue;
res=max(res,solve(s,t));
}
}
printf("%I64d\n",res);
}
return 0;
}
本文介绍了一种通过暴力枚举括号位置来解决特定形式算术表达式的算法实现。针对算术表达式中乘法运算符数量不超过15的特点,利用栈进行中间结果计算,实现了所有可能括号组合的遍历,最终找到最大计算结果。
&spm=1001.2101.3001.5002&articleId=47397089&d=1&t=3&u=5af42cb84dfd4c439227d5d203a84f25)
587

被折叠的 条评论
为什么被折叠?



