题目链接
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;
}
京公网安备 11010502036488号