X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! ,其中a[i]为当前未出现的元素中是排在第几个(从0开始)。这就是康托展开
//康托展开
LL Work(char str[])
{
int len = strlen(str);
LL ans = 0;
for(int i=0; i<len; i++)
{
int tmp = 0;
for(int j=i+1; j<len; j++)
if(str[j] < str[i]) tmp++;
ans += tmp * f[len-i-1]; //f[]为阶乘
}
return ans; //返回该字符串是全排列中第几大,从0开始
}
例题: 点击打开链接,
样例输入3 abcdefghijkl hgebkflacdji gfkedhjblcia样例输出
1 302715242 260726926
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char s[15];
int f(int x)
{
int sum=1;
for(int i=2;i<=x;i++)
sum*=i;
return sum;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s",s);
int l=12;
int ans=0;
for(int i=0;i<l;i++)
{
int tmp=0;
for(int j=i+1;j<l;j++)
if(s[j]<s[i]) tmp++;
ans+=tmp*f(l-i-1);
}
printf("%d\n",ans+1);
}
}
//康托展开逆运算
void Work(LL n,LL m)
{
n--;
vector<int> v;
vector<int> a;
for(int i=1;i<=m;i++)
v.push_back(i);
for(int i=m;i>=1;i--)
{
LL r = n % f[i-1];
LL t = n / f[i-1];
n = r;
sort(v.begin(),v.end());
a.push_back(v[t]);
v.erase(v.begin()+t);
}
vector<int>::iterator it;
for(it = a.begin();it != a.end();it++)
cout<<*it;
cout<<endl;
}
第几是谁?
时间限制:
3000 ms | 内存限制:
65535 KB
难度:
3
-
描述
- 现在有"abcdefghijkl”12个字符,将其按字典序排列,如果给出任意一种排列,我们能说出这个排列在所有的排列中是第几小的。但是现在我们给出它是第几小,需要你求出它所代表的序列.
-
输入
-
第一行有一个整数n(0<n<=10000);
随后有n行,每行是一个整数m,它代表着序列的第几小;
输出
- 输出一个序列,占一行,代表着第m小的序列。 样例输入
-
3 1 302715242 260726926
样例输出
-
abcdefghijkl hgebkflacdji gfkedhjblcia
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
typedef long long LL;
int f[] = {1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800};
//康托展开逆运算
void Work(LL n,LL m)
{
n--;
vector<int> v;
vector<int> a;
for(int i=1;i<=m;i++)
v.push_back(i);
for(int i=m;i>=1;i--)
{
LL r = n % f[i-1];
LL t = n / f[i-1];
n = r;
sort(v.begin(),v.end());
a.push_back(v[t]);
v.erase(v.begin()+t);
}
vector<int>::iterator it;
for(it = a.begin();it != a.end();it++)
{
// cout<<*it;
char c=*it-1+'a';
cout<<c;
}
cout<<endl;
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
char s[11];
scanf("%d",&n);
Work(n,12);
}
}