组合数学(全排列)+DFS CSU 1563 Lexicography
生活随笔
收集整理的這篇文章主要介紹了
组合数学(全排列)+DFS CSU 1563 Lexicography
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
題目傳送門
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. 用上面的思路 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 */ 2. 用next_permutation函數?
轉載于:https://www.cnblogs.com/Running-Time/p/4444286.html
總結
以上是生活随笔為你收集整理的组合数学(全排列)+DFS CSU 1563 Lexicography的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Eclipse新建菜单中添加JSP
- 下一篇: 避免button处理事件过程中 点击按钮