Given a string of characters, we can permute the individual characters to make new strings. At first we order the string into alphabetical order. Then we start permuting it.
For example the string 'abba' gives rise to the following 6 distinct permutations in alphabetical order.
aabb 1
abab 2
abba 3
baab 4
baba 5
bbaa 6
Given a string, you have to find the nth permutation for that string. For the above case 'aabb' is the 1st and 'baab' is the 4th permutation.
Input
Input starts with an integer T (≤ 200), denoting the number of test cases.
Each case contains a non empty string of lowercase letters with length no more than 20 and an integer n (0 < n < 231).
Output
For each case, output the case number and the nth permutation. If the nth permutation doesn't exist print 'Impossible'.
Sample Input |
Output for Sample Input |
|
3 aabb 1 aabb 6 aabb 7 |
Case 1: aabb Case 2: bbaa Case 3: Impossible |
给你一个字符串,让你输出这个串的第k个排列。
这里用到了逆康拓展开。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 1e9
#define endl '\n'
#define mod 100000007
#define LL long long
using namespace std;
LL f[30];
int num[30];
LL kangtuo(int n)
{
LL ans = f[n];
for(int i=0;i<26;i++)
ans /= f[num[i]];
return ans;
}
int main(void)
{
int T,n,i,j;
LL k;
char a[30];
scanf("%d",&T);
f[0] = 1;
for(i=1;i<=20;i++)
f[i] = f[i-1]*i;
int cas = 1;
while(T--)
{
scanf("%s%lld",a,&k);
n = strlen(a);
memset(num,0,sizeof(num));
for(i=0;i<n;i++)
num[a[i]-'a']++;
printf("Case %d: ",cas++);
if(k > kangtuo(n))
{
printf("Impossible\n");
continue;
}
for(i=1;i<=n;i++)
{
for(j=0;j<26;j++)
{
if(num[j] == 0)
continue;
num[j]--;
LL t = kangtuo(n-i);
if(k > t)
{
k -= t;
num[j]++;
}
else
{
printf("%c",'a'+j);
break;
}
}
}
printf("\n");
}
return 0;
}

本文介绍了一种求解字符串第K个排列的算法实现,通过逆康托展开方法,针对给定的字符串和整数K,输出该字符串的第K个字典序排列。文章提供了完整的C++代码示例,并解释了如何处理重复字符的情况。
2241

被折叠的 条评论
为什么被折叠?



