题目链接

https://ac.nowcoder.com/acm/contest/7412/C

解题思路

递归匹配呗,反正我不会!WTCL!WTCL!WTCL!!!请骂我!!!
难就难在实现上,方法谁都懂,就是实现不出来!

AC代码1

我感觉代码1比代码2好理解,但是比代码2难自己实现。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int i=0;//i要全局
string s;
ll solve(){
    ll res=0,a=0;
    for(;i<s.size();i++){
        ll tmp=0;
        while(isdigit(s[i])) tmp=tmp*10+(s[i++]-'0');
        res+=a*max(tmp,1LL);
        a=0;
                /*
                不知道你能不能理解为什么循环找数字。
                其实不是先循环找数字,而是每次找的数字都是上一个solve到的右括号后的数字。
                比如(HHH)444,第一次从主函数进入slove,因为没有数字,所以第一个solve里的while循环进行不了;
                匹配到左括号,进入从主函数的solve中进入solve函数;
                这次进入solve依旧没法进入while,但是a存下了HHH的和,匹配到右括号break,返回到上一层的solve中,此时a依旧存的是HHH的和吧;
                匹配到数字了,终于进入while了,tmp存下了444,再用a与tmp相乘,就是HHH的和与444相乘,得到了要的结果res。
                所以,能看出什么呢?res的刷新用的是上一层solve中得到的a的值,对于本层solve就得直接用a去乘数字了,所以本层中要先去找数字相乘再进行别的操作。
                */
        if(isalpha(s[i])) a+=s[i]-'A'+1;
        if(s[i]=='(') i++,a=solve();//i++,跳过左括号并进入solve
        else if(s[i]==')') break;
    }
    res+=a;//万一字符串存在后缀字母,就加上
    return res;
}
int main(){
    cin>>s;
    cout<<solve()<<endl;
}

AC代码2

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+10;
int pos[N];
stack<int> stk;
string s;
ll solve(int l,int r){
    ll res=0,num=0;
    for(int i=l;i<=r;i++){
        if(s[i]=='('){//(
            ll tmp=solve(i+1,pos[i]-1);
            i=pos[i]+1;
            while(i<=r && isdigit(s[i])) num=num*10+(s[i++]-'0');
            res+=tmp*max(num,1LL);
            num=0;
            i--;
        }
        else {
            if(i+1<=r && isdigit(s[i+1])){//i必然不是右括号,因为右括号是循环的右边界;如果i不是左括号,且i+1是十进制数,那么i必然是字母,因为如果i不是字母怎么会出现数字。总而言之,这个判断说明i为字母,i以后为若干数字
                int x=i+1;
                while(x<=r && isdigit(s[x])) num=num*10+(s[x++]-'0');
                res+=num*(s[i]-'A'+1);
                i=x-1;
                num=0;
            }
            else res+=s[i]-'A'+1;//i是字母,且i+1也是字母,即i以后存在若干个字母
        }
    }
    return res;
}
int main(){
    cin>>s;
    int n=s.length();
    s='.'+s;
    for(int i=1;i<=n;i++){
        if(s[i]=='(') stk.push(i);
        else if(s[i]==')') pos[stk.top()]=i,stk.pop();//左右括号匹配一下,pos[左括号的位置]=与之匹配的左括号的位置
    }
    cout<<solve(1,n)<<endl;
}