LightOJ 1060 - nth Permutation (逆康托展开的思想)

原创 2015年11月21日 04:17:05

题意:

n<=20k

分析:

f=n!/(cnta!cntb!cntz!)
点击这里
dp

代码:

//
//  Created by TaoSama on 2015-11-20
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
#define pr(x) cout << #x << " = " << x << "  "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;

typedef long long LL;
int n, cnt[26];
LL k, fact[25] = {1};
char s[25];

int main() {
#ifdef LOCAL
    freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);
//  freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);
#endif
    ios_base::sync_with_stdio(0);

    int t; scanf("%d", &t);
    int kase = 0;
    for(int i = 1; i <= 20; ++i) fact[i] = fact[i - 1] * i;
    while(t--) {
        scanf("%s%lld", s + 1, &k);
        n = strlen(s + 1);
        memset(cnt, 0, sizeof cnt);
        for(int i = 1; i <= n; ++i) cnt[s[i] - 'a']++;

        printf("Case %d: ", ++kase);
        LL maxk = fact[n];
        for(int i = 0; i < 26; ++i) maxk /= fact[cnt[i]];
        if(k > maxk) {puts("Impossible"); continue;}

        for(int i = 1; i <= n; ++i) {
            for(int j = 0; j < 26; ++j) {
                if(!cnt[j]) continue;
                --cnt[j];
                LL tmp = fact[n - i];
                for(int k = 0; k < 26; ++k)
                    tmp /= fact[cnt[k]];
                if(k <= tmp) {
                    putchar('a' + j);
                    break;
                }
                ++cnt[j];
                k -= tmp;
            }
        }
        puts("");
    }
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

lightoj 1060 - nth Permutation 组合数学

给定一个字符串和k,求字符串第k大字典序的排列... 康拓逆展开...可以求没有重复元素的第k个排列,有重复的话,方法是一样的,只是求解方案数变了。 由单纯的阶乘变为len!/cnt[i]!(0 ...

UVa 11525 - Permutation (线段树 树状数组 康托展开式)

UVA - 11525 Permutation Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld &...

leetcode[60]Permutation Sequence 以及 全排列的编码与解码——康托展开 (附完整代码)

leetcode[60]Permutation Sequence 以及 全排列的编码与解码——康托展开 (附完整代码)...

UVA 11525 Permutation-不重复全排列的第n项-(康托展开)

康托展开的公式 :  X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! ai为整数,并且0 适用范围:没有重复元素的全排列 ...
  • viphong
  • viphong
  • 2016年08月18日 21:49
  • 177

LightOJ-1165 Digit Dancing(BFS+康托展开)

B - Digit Dancing Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submi...

求排列中第k大的数--逆康托展开

简单介绍下: 这个方法还是用例子来说比较好 例1 {1,2,3,4,5}的全排列,并且已经从小到大排序完毕 (1)找出第96个数 首先用96-1得到95 用95去除4! 得到3余23...

康托展开的逆Hdoj1027

#include #include int ans[8]; int jc[9]; bool used[9]; void jjc() { jc[0]=jc[1]=1; for(in...

逆康托展开

简单介绍下:这个方法还是用例子来说比较好例1 {1,2,3,4,5}的全排列,并且已经从小到大排序完毕(1)找出第96个数首先用96-1得到95用95去除4! 得到3余23用23去除3! 得到3余5用...

全排列的编码与解码——康托展开及其逆展开

一、康托展开:全排列到一个自然数的双射   X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0!   ai为整数,并且0...

康托逆展开式

关于康托展开式的问题我已经在第一篇文章提到了,需要的朋友可以点进去看看。 ACM题目之排列序数 康托逆展开式就是给你一个数组,然后让你求出其全排列第n大的序列. 这里借用百度百科给的大家解释下 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:LightOJ 1060 - nth Permutation (逆康托展开的思想)
举报原因:
原因补充:

(最多只允许输入30个字)