第几是谁?
- 描述
- 现在有"abcdefghijkl”12个字符,将其按字典序排列,如果给出任意一种排列,我们能说出这个排列在所有的排列中是第几小的。但是现在我们给出它是第几小,需要你求出它所代表的序列.
- 输入
- 第一行有一个整数n(0<n<=10000);
随后有n行,每行是一个整数m,它代表着序列的第几小; - 输出
- 输出一个序列,占一行,代表着第m小的序列。
- 样例输入
-
3 1 302715242 260726926
- 样例输出
-
abcdefghijkl hgebkflacdji gfkedhjblcia
先了解下康拓展开和逆康拓展开。#include <iostream>
using namespace std;int main()
{
int fac[12]; //保存1-12的阶乘
fac[1]=1;
for(int i=2;i<=12;i++)
fac[i]=fac[i-1]*i;
int n,a[12],b[12];
cin>>n;
while(n--)
{
int m;
cin>>m;
m--;
for(int i=1;i<=12;i++)//记录每个字符在使用之前时候被使用过,
b[i]=i;
for(int i=1;i<12;i++)
{
int result;
result=m/fac[12-i]; //求比当前位置小的有几种情况
a[i]=b[result+1]; //比如:比有三个比***小的字符,则***=4+ASCII;
for(int j=result;j<=12;j++) //比如:比有三个比***小的字符,则***=4+ASCII,但***已经出现过,所以
b[j]=b[j+1]; //****= 4+ASCII+1;
m-=result*fac[12-i];//康托展开:a[n]*(n-1)!+a[n-1]*(n-2)!+......+a[0]=sum;
} //则 a[n-1]*(n-2)!+......+a[0]=sum- a[n]*(n-1)!;
a[12]=b[1]; //
for(int i=1;i<=12;i++)
printf("%c",a[i]+96);
cout<<endl;
}
return 0;
}