题意:合法的字符串序列:由小写字母组成,每一个字符比后一个字符ASCII码要大
将合法字符串序列按字典序编码,第一小的编码为1,第二小的编码为2...依次类推
如:a->1,b->2……z->26,ab->27……vwxyz->83681.
给定一个字符串,若其合法,输出其编码,否则输出0
分析:先判断是否合法,若合法,再算其编码
计算编码即计算比该字符串小的字符串的个数,再加1即为其编码
比该字符串小的:长度比该字符串小的个数+长度与其相等的个数
第一部分:小于字符串长度的。
假设长度是5
那么要枚举长度是4,3,2,1,一共有多少的字符串符合要求。
当长度是1的时候,有=26个;
当长度是2的时候,有=
;
长度为3有 ,4 也是这样、、、依次类推
第二部分:等于字符串长度。
第一小部分:对于s[0]
枚举从a开始到s[0]-1,字符串长度为len-1。
第二小部分:s[1]至s[len-1]
对于每一个s[i]来说,枚举从s[i-1]+1到s[i]-1,字符串长度为len-1-i
#include<stdio.h>
#include<string.h>
int c[30][30],n,sum;
char s[15];
void com() //求组合数
{
int i,j;
memset(c,0,sizeof(c));
for(i=0;i<=26;i++)
c[i][0]=c[i][i]=1;
c[0][0]=0;
for(i=1;i<=26;i++)
for(j=1;j<i;j++)
c[i][j]=c[i-1][j-1]+c[i-1][j];
}
bool judge() //判断是否为合法字符串
{
int i;
for(i=1;i<n;i++)
if(s[i-1]>=s[i])
return false;
return true;
}
void cal_num() //计算编码
{
int i,j;
for(i=1;i<n;i++) //先统计长度比n小的部分
sum+=c[26][i];
for(i='a';i<s[0];i++) //统计长度等于n的部分
sum+=c['z'-i][n-1];
for(i=1;i<n;i++){
for(j=s[i-1]+1;j<s[i];j++)
sum+=c['z'-j][n-1-i];
}
}
int main()
{
com();
while(scanf("%s",s)!=EOF){
n=strlen(s);
if(!judge()){
printf("0\n");
continue;
}
sum=1;
cal_num();
printf("%d\n",sum);
}
return 0;
}