题意
将字符串转换为对应权值,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; }