题目传送门
题目描述
编码工作常被运用于密文或压缩传输。这里我们用一种最简单的编码方式进行编码:把一些有规律的单词编成数宇。
字母表中共有26个字母{a,b,…,z},这些特殊的单词长度不超过6且字母按升序排列。把所有这样的单词放在一起,按字典顺序排列,一个单词的编码就对应着它在字典中的位置。
例如:
a→1 b→2 z→26 ab→27 ac→28
你的任务就是对于所给的单词,求出它的编码。
输入格式
仅一行,被编码的单词。
输出格式
仅一行,对应的编码。如果单词不在字母表中,输出0。
输入输出样例
输入
ab输出
27
解析: 假设待处理的字符串 s = cs'(其中c为第一个字母, 令 c - 'a' + 1 = t,s'为除去第一个字母剩下的字符串)。那么我们就可以 f[s] = + f[s'] (其中 i 从 1 ~ t) ;因为s'的长度比s的长度少一,因此不断递归下去,当字符串长度为1时即可停止( f[c] = c - 'a' + 1)
代码:(递归)
#include<bits/stdc++.h>
using namespace std;
//计算组合数
int C(int n, int m){
int ans = 1;
for(int i = 1; i <= m; i++){
ans *= (n - m + i);
ans /= i;
}
return ans;
}
int solve(string s){
int len = s.size();
//字符串首位
int t = s[0] - 'a' + 1;
//剩下的字符串
string ss = s.substr(1, len - 1);
//长度为1,直接可得到答案
if(len == 1) return t;
//求和
int sum = 0;
for(int i = 1; i <= t; i++) sum += C(26 - i, len - 1);
//递归处理
return sum + solve(s.substr(1, len - 1));
}
int main(){
string s;
cin >> s;
bool flag = true;
//判断字符串是否符合题意
for(int i = 0; i < s.size() - 1; i++)
if(s[i] >= s[i + 1] || s[i] < 'a' || s[i] > 'z'){
flag = false;
break;
}
if(!flag) puts("0");
else cout << solve(s) << endl;
return 0;
}