码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 1850-Code(组合数学)

时间:2015-04-04 09:14:46      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:


Code
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 8505   Accepted: 4030

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

题意:

 将字母a-z进行排列,然后再进行编号,符合以下三个规则:
1、在长度上是递增的;
2、长度一样的时候,按照字典序进行排列;
3、以a为开始编排,样例如下:
a - 1
b - 2
...
z - 26
ab - 27
...
az - 51
bc - 52
...
vwxyz - 83681
...

思路:因为是升序哒,所以但凡事输入的字符串存在降序的序列,就直接输出0,然后结束。

这道题大体来说分两部分来求解:

1、算出长度小于所给字符串的所有字符串的个数;
2、算出长度等于所给字符串但排在前面的所有字符串的个数。

对于长度小于所给字符串的情况,我们可以先分别求出个长度的个数,然后相加。通过推可以得出n字符串的长度的排列组合数是技术分享

对于小于当前长度的序列直接将从1-(len-1)字符串长度的序列全部相加,对于和当前len长度相同的,请看下面的例子:

假设所给字符串为vwxyz,长度为5,第一个字符为‘v‘,则我们可以假定第一个字符从‘a‘到‘z‘:
当假定字符串为‘a‘时,后面4个位置可以安排大于‘a‘的25个字符,所以有技术分享种选择方法;
当假定字符串为‘b‘时,后面4个位置可以安排大于‘b‘的24个字符,所以有技术分享种选择方法;
............
当假定字符串为‘u‘时,后面4个位置可以安排大于‘u‘的5个字符,所以有技术分享种选择方法;
然后对于后面的字符也是一样的进行求解,再将这些结果全部加起来就可


#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <map>
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const double pi= acos(-1.0);
int c[27][27]={0};
void C()//计算当前字符串长度下的符合规则的排列总数
{
    int i,j;
    for(i=0;i<27;i++){
        c[i][0]=1;
        c[i][i]=1;
    }
    //以下是排列组合的递推公式
    for(i=1;i<27;i++)
    for(j=1;j<27;j++)
        c[i][j]=c[i-1][j-1]+c[i-1][j];
}
int main()
{
    int i,j,k;
    char str[15];
    LL sum;
    int cnt;
    C();
    while(~scanf("%s",str)){
        int len=strlen(str);
        sum=0;
        for(i=0;i<len-1;i++)
        if(str[i]>str[i+1]){
            printf("0\n");
            return 0;
        }
        for(i=1;i<len;i++)
            sum+=c[26][i];//c[26][i]表示长度为i的字符串的排列个数
        for(i=0;i<len;i++){
            if(i==0)
                cnt='a';
            else
                cnt=str[i-1]+1;//根据升序规则,当前位置的cnt至少要比str前一位置的字符大1,因为每一个的排列的开始为a,ab,abc,abcd
            while(cnt<str[i]){//根据升序规则,当前位置的ch最多只能比str这个位置实际上的字符小1
                sum+=c['z'-cnt][len-i-1];//小于等于ch的字符串的排列个数在上面已经计算,所以当前能够选择的字符总数为'z'-cnt
                                         //cnt位置后面(不包括cnt)剩下的位数,就是从'z'-cnt选择len-1-i个字符
                cnt++;
            }
        }
        printf("%lld\n",sum+1);//sum算的是比当前str小的所有的组合数,并不包括其本身,所以在这加1.
    }
    return 0;
}


POJ 1850-Code(组合数学)

标签:

原文地址:http://blog.csdn.net/u013486414/article/details/44860765

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!