回复 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; }