回复 29楼 beyondyf
没提交地址的 自己想的呵呵
你的想法完全正确的, 我就是看到那个置顶贴
然后想到了一个算法 然后就出了这题, 嘿嘿
程序代码:#include<stdio.h>
#define FACT_MAX 20
long long F[FACT_MAX + 1];
long long permutation_to_number(int * p, int len)
{
int i, j, c;
long long sum;
for(sum = i = 0; i < len; sum += c * F[len - 1 - i++])
for(c = 0, j = i + 1; j < len; j++)
if(p[i] > p[j]) c++;
return sum;
}
void number_to_permutation(long long num, int len, int * p)
{
int i, j, t;
num %= F[len--];
for(i = 0; i <= len; i++) p[i] = i + 1;
for(i = 0; num; i++)
{
j = i + num / F[len - i];
for(t = p[j]; j > i; j--)
p[j] = p[j - 1];
p[i] = t;
num %= F[len - i];
}
}
int main()
{
int p[24], m, n, i;
long long k;
for(F[0] = i = 1; i <= FACT_MAX; i++) F[i] = F[i - 1] * i;
for(scanf("%d", &m); m--; puts(""))
{
scanf("%d%I64d", &n, &k);
for(i = 0; i < n; scanf("%d", &p[i++]));
k += permutation_to_number(p, n);
number_to_permutation(k, n, p);
for(printf("%d", p[0]), i = 1; i < n; printf(" %d", p[i++]));
}
return 0;
}


程序代码:#include<iostream>
using namespace std;
long long f[21] = {0,1,2};
long long cantor(int num[], int len)
{
long long sum = 0;
for(int i=0; i<len; ++i) {
int tmp = 0;
for(int j=i+1; j<len; ++j)
if(num[i] > num[j])
tmp++;
sum += f[len-i-1]*tmp;
}
return sum+1;
}
void uncantor(int num[], long long k, int len)
{
int flag[30] = {0};
for(int i=len-1; i>0; --i) {
long long tmp = k / f[i];
k = k % f[i];
int j;
for( j=1; j<=len; ++j) {
if(flag[j]) continue;
if( tmp == 0) break;
tmp--;
}
num[len-i-1] = j;
flag[j] = 1;
}
for(int i=1; i<=len; ++i)
if( !flag[i] ) {
num[len-1] = i;
break;
}
}
int main()
{
int k;
for(int i=3; i<=20; ++i)
f[i] = f[i-1] * i;
cout << f[19] << endl;
while( cin >> k ) {
while( k-- ) {
long long n,m;
cin >> n >> m;
int num[30];
for(int i=0; i<n; ++i)
cin >> num[i];
long long cnt = cantor(num, n);
if( (cnt + m) % f[n] ) m =(cnt+m) %f[n];
else m =f[n];
uncantor(num, m-1, n);
cout << num[0];
for(int i=1; i<n; ++i)
cout << " " << num[i];
cout << endl;
}
}
return 0;
}