Code
Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 10060 Accepted: 4817
Description
Transmitting and memorizing information is a task that requires different coding systems for the best use of the available space. A well known system is that one where a number is associated to a character sequence. It is considered that the words are made only of small characters of the English alphabet a,b,c, …, z (26 characters). From all these words we consider only those whose letters are in lexigraphical order (each character is smaller than the next character).
The coding system works like this:
• The words are arranged in the increasing order of their length.
• The words with the same length are arranged in lexicographical order (the order from the dictionary).
• We codify these words by their numbering, starting with a, as follows:
a - 1
b - 2
…
z - 26
ab - 27
…
az - 51
bc - 52
…
vwxyz - 83681
…
Specify for a given word if it can be codified according to this coding system. For the affirmative case specify its code.
Input
The only line contains a word. There are some constraints:
• The word is maximum 10 letters length
• The English alphabet has 26 characters.
Output
The output will contain the code of the given word, or 0 if the word can not be codified.
Sample Input
bf
Sample Output
55
计数问题可转化为数位dp,与p进制不同,后面的位不能比前面的位大,于是可从长度1到当前str的长度从a开始计数。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define ll long long
char str[15];
long long dp[11][30];
int num[15];
void init(){
for(int j = 1;j <= 26;++j){
dp[1][j] = 1;
}
for(int i = 2;i <= 10;++i){
for(int j = 1;j <= 26;++j){
for(int k = j + 1;k <= 26;++k){
dp[i][j] += dp[i - 1][k];
}
}
}
}
long long dfs(int i,int j,bool flag){
if(i == 0)
return 1;
if(flag){
int limit = num[i];
long long sum = 0;
for(int k = j + 1;k <= limit;++k){
sum += dfs(i - 1,k,k == limit);
}
return sum;
}
else{
return dp[i + 1][j];
}
}
long long solve(){
int k = 1,len = strlen(str);
for(int i = len - 1;i >= 0;--i){
int t = str[i] - 'a' + 1;
num[k++] = t;
}
long long sum = 0;
for(int i = 1;i < k;++i){
bool flag = i == k - 1 ? true : false;
int limit = flag ? num[i] : 26;
for(int j = 1;j <= limit;++j){
sum += dfs(i - 1,j,j == limit);
}
}
return sum;
}
int main()
{
init();
while(~scanf("%s",str)){
bool flag = true;
for(int i = 1;str[i] != '\0';++i){
if(str[i] <= str[i - 1]){
flag = false;
break;
}
}
if(flag){
cout << solve() << endl;
}
else{
cout << 0 << endl;
}
}
return 0;
}