您的位置:首页 > 其它

POJ 1850 Code (组合数学)

2014-09-25 09:17 253 查看
题意:

求str在字典中的编号。字典中的字符串都是严格升序排列,而且长度递增的。a-z为1-26,然后是ab-az

分别编号为27-51,然后是bc-bz。。。

分析:

1、首先可以确定长度比str小的总共有多少个。

比如长度为2的就有C(26,2)个,相当于26个字符中选2个,由于默认是升序排列,不会重复,排列顺序也

固定,所以只要选出来就可以了。

依次类推,长度为i的串的个数分别为C(26,i)

2、然后考虑长度为strlen(str)且在str前面的串的个数,枚举每个位置可取的字符。

比前一个字符大,比后一个字符小。(如果是第一个,则是从a到它后一个字符减1的字符)

#include<cstdio>
#include<iostream>
#include<cstring>

using namespace std;

char str[15];
int c[30][30];

void yh()
{
    for(int i=0;i<=26;i++)
    {
        for(int j=0;j<=i;j++)
        {
            if(j==0 || i==j)
                c[i][j] = 1;
            else c[i][j] = c[i-1][j-1]+c[i-1][j];
        }
    }
    c[0][0] = 0;
}

int main()
{
    yh();
    while(scanf("%s",str)!=EOF)
    {
        int len = strlen(str),flag = 0,sum;
        for(int i=1;i<len;i++)
        {
            if(str[i]<=str[i-1])
            {
                puts("0");
                flag = 1;
                break;
            }
        }
        if(flag) continue;
        sum = 0;
        for(int i=1;i<len;i++)
            sum+=c[26][i];
        for(int i=0;i<len;i++)
        {
            char ch = (i==0)?'a':str[i-1]+1;
            while(ch<str[i])
            {
                sum+=c['z'-ch][len-1-i]; //ch位置后面(不包括ch)剩下的位数,就是从'z'-ch选择len-1-i个字符
                ch++;  //因为编号从0开始,所以是len-1-i而不是len-i
            }
        }
        printf("%d\n",sum+1);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: