题意
将字符串转换为对应权值,A-Z为1-26,若字母后面存在数字,则将前面字母或括号内权值乘以后面的数字
注意多种特殊情况。
题解
(题解写着写着发现一组hack数据把自己昨天的代码hack了...这题数据有锅呀,hack数据 ABC5 答案应该是18)
对左右括号,数字,字母进行分类讨论即可.
将每对括号中的字符串当作一段,使用栈模拟递归..(或者不传参递归,传参字符串把内存传爆了)
具体见注释。
code
#include <bits/stdc++.h>
#define reg register
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define inf 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
#define e exp(1.0)
#define ios ios::sync_with_stdio(false)
#define rep(i,l,r) for(int i=(l);i<(r);i++)
using namespace std;
const int maxn = 2e5 + 10;
const int mod = 1e9 + 7;
bool isnum(char x) //判断是否为数字
{
if(x >= '0' && x <= '9') return 1;
else return 0;
}
bool isalp(char x){ //判断是否为字母
if(x >= 'A' && x <= 'Z') return 1;
else return 0;
}
stack<ll> sk1,sk2,sk3; //用来保存当前段内res,alpnow,numnow
ll cal(string s){
ll res = 0; // 当前段内的res所有权值和
ll alpnow = 0;//当前段内字母权值
ll numnow = 0;//当前段内数字大小 每个小段使用alpnow * numnow 就为当前字母数字段的权值和
for(int i = 0;i < s.size();++i){
if(s[i] == '('){ //遇到左括号进入下一段入栈并清空
sk1.push(res);
sk2.push(alpnow);
sk3.push(numnow);
res = 0;
alpnow = 0;
numnow = 0;
}
else if(s[i] == ')'){ //遇到右括号出栈恢复值
ll tmp = res;
res = sk1.top();sk1.pop();
alpnow = sk2.top();sk2.pop();
numnow = sk3.top();sk3.pop();
if(i+1 < s.size() && isnum(s[i+1])){ //若括号后面有数字,则将括号内算作字母权值和。否则直接加到总权值和即可
alpnow += tmp;
}
else res += tmp;
}
else if(isnum(s[i])){ //遇到数字
numnow = numnow * 10 + (s[i] - '0');
if(i+1 == s.size() || !isnum(s[i+1])){ //若下一个字符不是数字,将此段权值算出来
res += numnow * alpnow;
numnow = 0;
alpnow = 0;
}
}
else{ //遇到字母
alpnow += s[i] - 'A' + 1;
if(i + 1 == s.size() || (!isnum(s[i+1]))){ //若遇到下一个字符不是数字,将字母权值加和
res += alpnow;
alpnow = 0;
}
}
}
return res;
}
int main()
{
string s;
while(cin>>s){
ll res = cal(s);
cout<<res<<endl;
}
return 0;
} 
京公网安备 11010502036488号