POJ - 1850 Code——组合数

题意:

定义s为只由26个小写英文字母组成的长度任意的串,且串中的字母严格升序。

定义集合S为长度10以下的s的集合,S中的元素优先按照串的长度排序,长度相同按照字典序排序。

输入一个串str,若str在S中则输出str是S的第几小,若str不在S中输出0

思路:

组合数

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
char s[20];
long long c[50][50], len[50];
void init() {
    c[0][0] = 1;
    for (int i = 1; i <= 26; i++) {
        c[i][0] = 1;
        for (int j = 1; j <= i; j++) {
            c[i][j] = c[i-1][j] + c[i-1][j-1];
        }
    }
    len[0] = 0;
    for (int i = 1; i <= 10; i++) len[i] = len[i-1] + c[26][i];
}
int main() {
    init();
    while (~scanf("%s", s)) {
        int n = strlen(s);
        bool ok = true;
        for (int i = 0; i < n - 1; i++) if (s[i] >= s[i+1]) { ok = false; break; }
        if (!ok) {
            printf("0\n");
            continue;
        }
        long long ans = 1;
        for (int i = 0, j = 0; i < n; i++) {
            int x = s[i] - 'a';
            if (i) j = s[i-1] - 'a' + 1;
            for (; j < x; j++) ans += c[26-(j+1)][n-i-1];
        }
        printf("%lld\n", ans + len[n - 1]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hao_zong_yin/article/details/80243277
今日推荐