POJ 1850 Code (组合数学)

Code

 

Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 9588 Accepted: 4584

 

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

 

题意

输出某str在字典中的位置。

 

思路

规定输入的字符串必须是升序序列,否则是非法字符串,如果出现非法字符串时,应该输出0,并且结束程序。

对于长度为1的字符串,有a,b,c,…z,共 C[26][1]=26 个。

对于长度为2的字符串:

​ 以a开头的,有ab,ac,…az,一共 C[25][1]=25 个。

​ 以b开头的,有bc,bd,…bz,一共 C[24][1]=24 个。

​ ……

​ 以x开头的,有xy,xz,一共 C[2][1]=2 个。

​ 以y开头的,有yz,一共 C[1][1]=1 个。

于是,长度为2的字符串个数有 C[25][1]+C[24][1]+...+C[2][1]+C[1][1]=C[26][2] 种。

因为有公式:

C[n][m]=∑{i=1->n−1}C[i][m-1]

同理

长度为3的字符串个数为 C[26][3] 个。

长度为4的字符串个数为 C[26][4] 个。

所以我们可以用一个循环计算所有小于str长度的字符串个数,剩下的,就是求长度等于str,但是在str字典序前面的字符串个数了。

对于字符串第一位,起始最小为’a’,其他位最小只能是它的前一位+1,因此,对于当前位所能进行变换的只有 [c[i−1]+1,c[i]−1] ,我们所要计算的是当前位的后几位,组合数需要在’z’-ch中选择剩余位数个,最终求得的和+1便是答案,+1的原因是因为我们所计算的是str前面的字符串个数。

 

AC 代码

#include <iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<cmath>
#include<stack>
#include<string.h>
#define PI (acos(-1))
using namespace std;
int C[27][27];
void init() //组合数打表
{
    C[1][0]=C[1][1]=1;
    for(int i=2; i<27; i++)
        for(int j=0; j<=i; j++)
        {
            if(j==0)C[i][j]=1;
            else C[i][j]=C[i-1][j-1]+C[i-1][j];
        }
}
int main()
{
    init();
    string c;
    while(cin>>c)
    {
        int len=c.length(),sum=0;
        for(int i=1; i<len; i++)
            if(c[i]<=c[i-1])
            {
                printf("0\n");
                return 0;
            }

        for(int i=1; i<len; i++)    //长度小于len的字符串
            sum+=C[26][i];

        for(int i=0; i<len; i++)    //长度等于len的字符串
        {
            char ch=i!=0?c[i-1]+1:'a';  //对于第一位,起始最小为'a',其余为当前已有位+1
            while(ch<c[i])
                sum+=C['z'-ch++][len-1-i];
        }
        printf("%d\n",sum+1);
    }
    return 0;
}