1 /*
2 题意:求第K个全排列
3 组合数学:首先,使用next_permutation 函数会超时,思路应该转变,
4 摘抄网上的解法如下:
5 假设第一位是a,不论a是什么数,axxxxxxxx一共有8!种选择。
6 297192 div 8! = 7,余14952,所以第一位是1-9中的第8个数,也就是8。
7 14952 div 7! = 2,余4872,所以第二位是3。
8 4872 div 6! = 6,余552,所以是第三位是1245679这七个数中的第7个,也就是 9。
9 552 div 5! = 4,余72,所以是124567中的第5个,也就是6。
10 72 div 4! = 2,余24,所以是4。
11 这时候就不用算了,因为24 = 4!,而剩下的数就是1257这4个,他们组成的排列的第
12 24个必然是7521。
13 以上解法只符合没有重复的序列,但是思路一致,把除法改为减法,每一次更新之后的全排列的数量
14 即 Ann / Amm 的个数,可以用DFS实现
15 */
16 #include <cstdio>
17 #include <iostream>
18 #include <algorithm>
19 #include <stack>
20 #include <cmath>
21 #include <cstring>
22 #include <vector>
23 using namespace std;
24
25 const int MAXN = 1e4 + 10;
26 const int INF = 0x3f3f3f3f;
27 char s[20];
28 int cnt[30];
29 int pos[20];
30 int len;
31
32 long long fact(int x)
33 {
34 long long res = 1;
35 for (int i=1; i<=x; ++i) res *= i;
36
37 return res;
38 }
39
40 long long f(int step)
41 {
42 long long res = fact (step);
43 for (int i=0; i<26; ++i) if (cnt[i]) res /= fact (cnt[i]);
44
45 return res;
46 }
47
48 void DFS(int step, long long k)
49 {
50 if (step == len)
51 {
52 for (int i=0; i<len; ++i) printf ("%c", 'A' + pos[i]);
53 puts (""); return ;
54 }
55
56 for (int i=0; i<26; ++i)
57 {
58 if (cnt[i] == 0) continue;
59 cnt[i]--;
60 long long tmp = f (len - step - 1);
61 if (tmp < k) {k -= tmp; cnt[i]++;}
62 else
63 {
64 pos[step] = i;
65 DFS (step+1, k);
66 return ;
67 }
68 }
69 }
70
71 int main(void) //CSU 1563 Lexicography
72 {
73 //freopen ("C.in", "r", stdin);
74
75 long long k;
76 while (scanf ("%s%lld", &s, &k) == 2)
77 {
78 if (s[0] == '#' && k == 0) break;
79
80 len = strlen (s);
81 memset (pos, 0, sizeof (pos));
82 memset (cnt, 0, sizeof (cnt));
83 for (int i=0; i<len; ++i) cnt[s[i]-'A']++;
84
85 DFS (0, k);
86 }
87
88 return 0;
89 }
90
91 /*
92 MAC
93 PICC
94 IGNORE
95 */
附带给出求1~9无重复数字的第K个全排列的两种方法

1 /* 2 假设第一位是a,不论a是什么数,axxxxxxxx一共有8!种选择。 3 297192 div 8! = 7,余14952,所以第一位是1-9中的第8个数,也就是8。 4 14952 div 7! = 2,余4872,所以第二位是3。 5 4872 div 6! = 6,余552,所以是第三位是1245679这七个数中的第7个,也就是 9。 6 552 div 5! = 4,余72,所以是124567中的第5个,也就是6。 7 72 div 4! = 2,余24,所以是4。 8 这时候就不用算了,因为24 = 4!,而剩下的数就是1257这4个,他们组成的排列的第 9 24个必然是7521。 10 */ 11 #include <cstdio> 12 #include <iostream> 13 #include <algorithm> 14 #include <stack> 15 #include <cmath> 16 #include <cstring> 17 #include <vector> 18 using namespace std; 19 20 const int MAXN = 1e4 + 10; 21 const int INF = 0x3f3f3f3f; 22 int num[11]; 23 int ans[11]; 24 int f[11]; 25 26 int main(void) 27 { 28 //freopen ("test_C.in", "r", stdin); 29 30 int k; 31 while (scanf ("%d", &k) == 1) 32 { 33 f[0] = 1; 34 for (int i=1; i<=9; ++i) {f[i] = f[i-1] * i; num[i] = i;} 35 36 int tot = 0; 37 int len = 9; 38 bool flag = false; 39 while (tot < len) 40 { 41 int pos = k / f[len-tot-1] + 1; 42 k %= f[len-tot-1]; 43 44 if (k == 0) {pos--; flag = true;} 45 46 int t = 0; 47 for (int i=1; i<=9; ++i) 48 { 49 if (num[i] != 0) 50 { 51 ++t; 52 if (t == pos) 53 { 54 printf ("%d", num[i]); 55 tot++; num[i] = 0; break; 56 } 57 } 58 } 59 60 if (flag) 61 { 62 for (int i=9; i>=1; --i) 63 { 64 if (num[i] != 0) printf ("%d", num[i]); 65 } 66 break; 67 } 68 } 69 puts (""); 70 } 71 return 0; 72 } 73 74 /* 75 839647521 76 */

1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <stack> 5 #include <cmath> 6 #include <cstring> 7 #include <vector> 8 using namespace std; 9 10 const int MAXN = 1e4 + 10; 11 const int INF = 0x3f3f3f3f; 12 int num[11]; 13 int ans[11]; 14 int f[11]; 15 16 int main(void) 17 { 18 //freopen ("test_C.in", "r", stdin); 19 20 int k; 21 while (scanf ("%d", &k) == 1) 22 { 23 for (int i=1; i<=9; ++i) num[i] = i; 24 25 int len = 9; 26 long long cnt = 0; 27 do{ 28 ++cnt; 29 if (cnt == k) break; 30 }while (next_permutation (num+1, num+1+len)); 31 32 for (int i=1; i<=9; ++i) 33 printf ("%d", num[i]); 34 puts (""); 35 } 36 return 0; 37 } 38 39 /* 40 839647521 41 */