题目意思:hdu3350,给定一个表达式,表达式只含数字、+和MAX(a,b)的表达式,其中MAX(a,b)表达式可能有嵌套,问表达式的计算结果和加法的次数。
解题思路:用结构体保存计算结果sum和加法的次数cnt,递归该表达式: 1.若第一个字母为数字,则求出该数字;若第一个字母为M,则分割成两部分,递归求出两部分的结构体u1和u2,如前半部分计算结果大于后半部分,则计算结构体u.sum=u1.sum且u.cnt=u1.cnt*2+u2.cnt,否则u.sum=u2.sum且u.cnt=u1.cnt+u2.cnt*2; 2.如该表达式后面还有+,则递归求出该表达式的结构体nu,计算u.sum+=nu.sum以及u.cnt+=nu.cnt+1。 3.返回计算结果
易错的点:MAX(a,b),如a>b才计算a表达式的加法乘以2,并非a>=b计算a表达式的加法乘以2。
代码明细:
//probID: hdu3350
//author: WiselyQY
//date: 2020-12-29
#include <bits/stdc++.h>
using namespace std;
//结构体:sum为计算结果,cnt为加法的累计数
struct Node
{
int sum, cnt;
};
string str;
Node dfs(int s, int e)
{
Node u;
u.sum=u.cnt=0;
//如果为数字则算出该数字
if(str[s]>='0' && str[s]<='9')
{
while(str[s]>='0' && str[s]<='9')
{
u.sum=u.sum*10+str[s]-'0';
s++;
}
}
//如果为MAX格式,则分割成两部分计算
else //if(str[i]=='M')
{
s+=4;//去掉MAX(
int left=1, j=s, k;
while(1)
{
if(str[j]==')' && left==1) break; //找到MAX结束的位置
if(str[j]==',' && left==1) k=j; //找到分割成两部分的位置
if(str[j]=='(') left++;
if(str[j]==')') left--;
j++;
}
Node u1=dfs(s,k); //计算MAX的前半部分
Node u2=dfs(k+1,j); //计算MAX的后半部分
if(u1.sum>u2.sum) {u.sum=u1.sum; u.cnt=u1.cnt*2+u2.cnt;} //如果前半部分大于后半部分则前半部分的cnt乘以2计算
else {u.sum=u2.sum; u.cnt=u1.cnt+u2.cnt*2;} //如果后半部分大于等于前半部分则后半部分的cnt乘以2计算
s=j+1;
}
//后面是否还有表达式,如果有则继续计算
if(str[s]=='+')
{
Node nu=dfs(s+1,e);
u.sum+=nu.sum;
u.cnt+=nu.cnt+1;
}
return u;
}
int main()
{
clock_t start,end;
start=clock();
#ifndef ONLINE_JUDGE
freopen(R"(D:\hdu\3350\in.txt)","r",stdin);
#endif
int T;
cin>>T;
while(T--)
{
cin>>str;
Node u=dfs(0, str.size());
cout<<u.sum<<" "<<u.cnt<<endl;
}
end=clock();
//printf("time=%lfs\n",(double)(end-start)/1000);
return 0;
}