POJ - 1850 Code(排列组合)

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
题目链接
参考题解1
参考题解2
这个题目求这个字符串的位序,其实就是求他前面的个数加一,并且输入的字符串都应该是严格递增的序列。先求 len<x的字符串数量,再求len==x,比当前字符串小的数量,只要选出一定的字母,那么他们的顺序就一定确定下来了,接下来就是找排列数的问题了。首先对杨辉三角预处理了一下,后面就是做数学题了。

#include <cstdio>
#include <cstring>
#define LL long long
using namespace std;
LL inf = 15;
LL n, m;
char tm[15];
LL c[30][30];

//预处理工作,存储杨辉三角所有值
void pre()
{
	 LL i, j;
	 for (i = 0; i <= 26; i++)
		 c[i][0] = 1;
	 for (i = 1; i <= 26; i++)
		 for(j = 1; j <= i; j++)
			 c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]);
}
//检验字符是否合法,要单调增
int check(char *s, int len)
{
    for (int i = 1; i < len; i++)
    {
        if (s[i] <= s[i - 1]) return 0;
    }
    return 1;
}

int main()
{
	pre();
    scanf("%s", tm);
    int len = strlen(tm);
    int ret = check(tm, len);
    if (!ret)
    {
        printf("0\n");
        return 0;
    }
    LL sum = 0, i, j;
    for (i = 1; i < len; i++)//累计所有长度小于len的字符串个数
        sum += c[26][i];

    //接下来算长度等于len的字符串个数
    if (tm[0] > 'a')
    {
        LL tmp = 0;
        for (i = 1; i <= tm[0] - 'a' - 1 + 1; i++) //tm[0]-'a'+1得到该字母对应数字,减一表示按照严格递增
            tmp += c[26 - i][len - 1];
        sum += tmp;
    }

    for (i = 1; i < len; i++)
    {
        if (tm[i] - 1 - tm[i - 1] > 0)
        {
            LL tmp = 0;
            for (j = tm[i - 1] - 'a' + 1 + 1; j <= tm[i] - 'a' + 1 - 1; j++) //tm[i-1]-'a'+1得到该字母对应数字,加一表示按照严格递增,不与i-1个字符重复,其他同理
                tmp += c[26 - j][len - i - 1];
            sum += tmp;
        }
    }
    printf("%lld\n", sum+1);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_40788897/article/details/83864474