题目:
假设,字母’a’代表值为1(即value(a)==1), ‘b’为2,…,’z’为26;如果出现连续相同字符,如aaaa…(连续k个a),这k个a的总权值会变成k*k*value(),如BB和bbbb的权值都是4*4*2=32;
分析:
顺序扫描一次就可以统计出来,时间复杂度O(n), 额外空间复杂度O(1),注意处理大数及边界。
第一行输入一个整数T(T<=1000),表示有T组数据。
接下来每行字符串长度不超过10000。
Sample Input:
5
bBb
bbbb
abcd
AB
CC
Sample output:
32
32
10
12
48
代码:
/* 统计权重 */
#include <iostream>
#include <string>
using namespace std;
unsigned long long subWeightCount(char c, int repeated);
unsigned long long weightCount(const string s)
{
unsigned long long weight = 0;
int repeated = 0;
char tmp = s[0];
for (int i = 0; i < s.length(); i++){
if (s[i] >= 'a' && s[i] <= 'z'){ //小写字母
if (s[i] == tmp || s[i] == tmp + 32) //如a==a或a==A+32
repeated++;
else{
weight += subWeightCount(tmp, repeated);
repeated = 1; //当前字母小写,更新为1
}
}
else if (s[i] >= 'A' && s[i] <= 'Z'){//大写字母
if (s[i] == tmp || s[i] == tmp - 32) //如A==A或A==a-32
repeated += 2;
else{
weight += subWeightCount(tmp, repeated);
repeated = 2;//当前字母大写,更新为2
}
}
else
return 0;
tmp = s[i]; //保存当前字母用于下一次比较
}
weight += subWeightCount(tmp, repeated);
return weight;
}
unsigned long long subWeightCount(char c, int repeated)
{
if(c >= 'a' && c <= 'z')
//注意repeate*repeated中间结果可能会越界,应强转成unsigned long long
return (unsigned long long)repeated*repeated*(c - 'a' + 1);
else if (c >= 'A' && c <= 'Z')
return (unsigned long long)repeated*repeated*(c - 'A' + 1);
}
int main()
{
int T;
string s;
cin >> T;
if (T > 1000)
return 0;
while (T--){
cin >> s;
/* 10000个z*/
/*for (int i = 0; i < 10000; i++)
s.push_back('z');
*/
cout << weightCount(s) << endl;
}
system("pause");
}