题目大意:给定一个只含有MAX和+操作的式子,求加法运行了多少次,其中MAX使用宏定义。
题解:注意一个规律,对于MAX(A,B)其中A中加a次,B中加b次若A>B,则加a*2+b次,否则a+b*2次。然后用递归处理这个字符串就可以了。
~心力憔悴地copy了代码,果然DFS太差了……
#include <cstdio> #include <iostream> #include <cstring> using namespace std; struct state{ state(int a,int b){s=a,k=b;} int s,k;//和,次数 }; state find(string str){ int in=0,len=str.length(),num=0;//当前位置,字符串长度 if(str[in]>='0'&&str[in]<='9'){//第一个字母是整数,读取这个数 while(in<len&&str[in]>='0'&&str[in]<='9')num=num*10+str[in++]-'0'; if(in>=len)return state(num,0);//如果只剩一个数,直接返回 else{//只能是a+B的形式,B是一个式子,处理B段 state st=find(str.substr(in+1)); return state(num+st.s,st.k+1); } }else if(str[in]=='M'){ in+=4; int cnt=1,mid=0; while(cnt>0){//匹配MAX()右括号的位置,并找出对应这个MAX的逗号的位置 if(str[in]=='(')cnt++; else if(str[in]==')')cnt--; if(str[in]==','&&cnt==1)mid=in; in++; } state le=find(str.substr(4,mid-4));//求MAX(A,B)中的A state ri=find(str.substr(mid+1,in-mid-2));//求MAX(A,B)中的B int p1,p2; if(le.s>ri.s){ p1=le.s; p2=le.k*2+ri.k; }else{ p1=ri.s; p2=le.k+ri.k*2; } if(in>=len-1){//已经到达末端 return state(p1,p2); }else{//MAX(A,B) + C的形式,求C state st=find(str.substr(in+1));//处理加号后面的部分 return state(p1+st.s,st.k+p2+1); } } } int main(){ int cas; char str[1005]; cin>>cas; while(cas--){ cin>>str; state rs=find(str); cout<<rs.s<<" "<<rs.k<<endl; } return 0; }