首页 > 代码库 > poj 1850 Code (组合数学)

poj 1850 Code (组合数学)

链接:poj 1850

题意:合法的字符串序列:由小写字母组成,每一个字符比后一个字符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 1850 Code (组合数学)