Stringer

来源:互联网 发布:windows隐藏的文件夹 编辑:程序博客网 时间:2024/06/03 07:48

Stringer

这里写图片描述
这里写图片描述
.
.
题意:已知有n中字母以及每种字母的个数,问第k大的序列是什么
.
.
解法:每个位置都进行从小到大枚举,看放该字母后面能否到达k,可以就放即可。
.
.
队友代码

#include <cstdio>#include <cstring>long long c[51][51];char ans[1000];int a[50];long long k;int main(){    c[0][0] = c[1][0] = c[1][1] = 1;    for (int i = 1; i <= 50; i++)    {        c[i][0] = c[i][i] = 1;        for (int j = 1; j < i; j++) c[i][j] = c[i - 1][j - 1] + c[i - 1][j];    }    int n;    while (~scanf("%d %lld", &n, &k))    {        if (n + k == 0) return 0;        int sum = 0;        for (int i = 1; i <= n; i++)        {            scanf("%d", &a[i]);            sum += a[i];        }        memset(ans, 0, sizeof(ans));        long long tot = 0;        for (int i = 1; i <= sum; i++)        {            tot = 0;            int j;            long long qqq = 0;            for (j = 1; j <= n; j++)            {                if (a[j] > 0)                {                    long long q = c[sum - i][a[j] - 1];                    long long s = sum - i - a[j] + 1;                    for (int k = 1; k <= n; k++)                    {                        if (k != j)                        {                            q *= c[s][a[k]];                            s -= a[k];                        }                    }                    qqq = tot;                    tot = tot + q;                }            //  printf("%d %d %d\n", i,j,tot);                if (tot > k) break;            }            --a[j];            k = k - qqq;            //printf("i:%d j:%d k:%d\n", i, j, k);            ans[i] = 'a' + j - 1;            /*for (int j = 1; j <= n; j++) printf("%d: %d ", j, a[j]);            printf("\n");*/        }        for (int i = 1; i <= sum; i++) printf("%c", ans[i]);        printf("\n");    }}
0 0
原创粉丝点击