康托(Cantor)展开
1. 输入一个组合,输出在对应数字从小到大的全排列中的编号。
输入:35142 ,输出:68
1 #include <stdio.h> 2 #include <string.h> 3 4 using namespace std; 5 6 int F[10] = {1,1,2,6,24,120,720,5040,40320,362880};//0!,1!,2!... 7 8 char A[10]; 9 10 int main() 11 { 12 int i, j, cnt, tmp, bit, ans; 13 scanf("%s", &A[1]); 14 bit = strlen(&A[1]); 15 ans = (A[1]-'0'-1) * F[bit-1]; 16 for (i = 2; i <= bit; ++i) { 17 tmp = 0; 18 for (j = 1; j < i; ++j) 19 if (A[j] < A[i]) ++tmp; 20 ans += (A[i]-'0'-1-tmp) * F[bit-i]; 21 } 22 printf("%d\n", ans+1); 23 return 0; 24 }
2. 输入 n, k, 求 1到n 这n个数组成的从小到大的全排列中第 k 位置的排列
输入:5 68 ,输出:35142
1 #include <stdio.h> 2 #include <string.h> 3 4 using namespace std; 5 6 int F[10] = {1,1,2,6,24,120,720,5040,40320,362880};//0!,1!,2!... 7 8 char A[10]; 9 10 bool f[10]; 11 12 int main() 13 { 14 int n, k, i, j, tmp; 15 scanf("%d%d", &n, &k), --k; 16 for (i = 1; i <= n; ++i) { 17 tmp = k / F[n-i] + 1; 18 for (j = 1; j <= n; ++j) 19 if (!f[j] && !(--tmp)) break; 20 putchar(j + '0'); 21 f[j] = true; 22 k %= F[n-i]; 23 } 24 return 0; 25 }