POJ 1850 Code(组合数学)

来源:互联网 发布:什么是淘宝推广 编辑:程序博客网 时间:2024/04/28 14:20

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


题目大意:求一个串(必须的递增否则输出0),问能经过多少步达到,从a开始逐渐演变。

思路:较难的组合数学,利用杨辉三角打个表,作为组合数的计算。分析如何变成当前的串可以大体分为2步,1)当位数小于当前串的位数;2)位数和当前串相同。

1)位数比当前的串小的时侯,直接ans+=c[26][i].

2)当位数相同的时候,


拿s=bdg这个字符串做例子。首先,s的长度len=3

已经是3位的,因为所谓的code是从a增到z再增到ab再增到yz再增到bdg的,即先从1位增到2位再增到3位的。

那么a增到z,code量是26个字母里面选1个,ab增到yz,code量是26个字母里选两个。

然后要计算yz到bdg的过程中有多少code量。

bdg的前面是经过a_ _的。那么a开头的3位有多少个呢?就是25个字母里选2个。因为空格里的字母不能小于等于a。,所以不会包含a。

然后看第2位,是一个d,d和b之间有个c,那么还需要计算c_有多少个,是23个里面选1个

然后看g,g和d之间有e和f。故就是1+1.

所以答案等于C[26][1]+C[26][2]+C[25][2] +C[23][1]+1+1

(摘自:http://m.blog.csdn.net/blog/a799581229/38146971)

//多组数据形式会WA,尽量做题的时候让用什么就用什么,不要乱创。。。

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<cmath>#define LL long long#define inf 0x3f3f3f3fusing namespace std;char a[1000];int c[30][30];void ini(){    for(int i=0;i<27;i++)//虽然从零开始但是以后的计算都是1开始        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];}int main(){    int n,m,x,k,i,j;    memset(c,0,sizeof(c));    ini();    gets(a+1);        int ans=0;        int l=strlen(a+1);        bool vis=false;        for(i=1;i<=l-1;i++)            if(a[i]>a[i+1])            {                printf("0\n");                return 0;            }        for(i=1;i<=l-1;i++)        {            ans+=c[26][i];        }        a[0]='a'-1;//为了使刚开始的部分不跃界        for(i=1;i<=l;i++)        {            for(j=a[i-1]-'a'+1;j<a[i]-'a';j++)            {//计算相邻两字母的间隔                ans+=c[25-j][l-i];            }        }        printf("%d\n",ans+1);    return 0;}


0 0