标签:poj
题意:合法的字符串序列:由小写字母组成,每一个字符比后一个字符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; }
标签:poj
原文地址:http://blog.csdn.net/acm_code/article/details/41013585