组合数学(全排列)+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相关推荐
- Leetcode46全排列DFS
链接 题目大意:给定一个数组,求出所有的全排列. 分析 DFS和回溯的方法. 回溯算法的核心 选择列表:表示当前可做的选择 路径:记录做过的选择 结束条件:遍历到树的底层,在这里是选择列表为空的时候. ...
- 第七届蓝桥杯决赛真题 - 凑平方数-全排列+dfs+set去重
题目: 凑平方数 把0~9这10个数字,分成多个组,每个组恰好是一个平方数,这是能够 办到的.比如:0, 36, 5948721再比如: 1098524736 1, 25, 6390784 0, 4, ...
- 全排列 DFS 回溯
//dfs全排列 #include<stdio.h> #include <string.h> char temp[5] = {'A','B','C','D'};//seed c ...
- Trie树 + DFS - CSU 1457 Boggle
Boggle Problem's Link: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1457 Mean: 给定n个串,有m个询问. 每个询 ...
- 全排列—dfs(递归算法手动模拟)
目录 1.dfs全排列深度优先算法思路导图 2.dfs递归思想 3.主旨展现 4.详解手动模拟 5.例题来喽 5.1例题(1)来喽 5.2例题(2)来喽 5.3例题(3)来喽 1.dfs全排列深度优先 ...
- 全排列(dfs、小白、详细解释)
目录 主函数 用来排序的函数 详细过程 代码 从键盘输入一个没有重复元素的字符串,输出这个字符串所有字符的全排列 输入格式: 一个字符串,输入保证字符串中没有重复的字符,字符串的长度不超过10,字符串 ...
- wikioi 1294 全排列 dfs
1294 全排列 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 给出一个n, 请输出n的所有全排列 输入描述 Input Desc ...
- [Leetcode][第60题][JAVA][第k个排列][回溯][DFS][剪枝]
[问题描述][中等] [解答思路] 1. 回溯搜索算法 + 剪枝 ,直接来到叶子结点 时间复杂度:O(N^2) 空间复杂度:O(N) import java.util.Arrays;public cl ...
- 【算法】蓝桥杯dfs深度优先搜索之排列组合总结
[导航] 上一篇文章 → <[算法]蓝桥杯dfs深度优先搜索之凑算式总结> 为了重申感谢之意,再次声明下文的大部分灵感均来自于[CSDN]梅森上校<JAVA版本:DFS算法题解两 ...
最新文章
- Go 学习笔记(18)— 函数(04)[闭包定义、闭包修改变量、闭包记忆效应、闭包实现生成器、闭包复制原对象指针]
- 派生类的继承方式【C++继承】
- Linux设备驱动归纳总结(一):内核的相关基础概念
- 设计模式之Builder (创建者模式)的一些个人理解(转)
- Python编程从入门到实践~字典
- ERROR: Failed building wheel for pycrypto
- 在CLR中自动本地化正在运行的.NET窗口
- 4月17日 键盘大小写指示indicator-lockkeys
- Photoshop CS6下载包下载 及破解安装教程
- 黑客是如何入侵网站?为什么企业网站需要渗透测试?
- pixi 小游戏_学习如何用pixi.js开发微信小游戏
- 最保险的“跳槽理由”
- 20220313_朴素贝叶斯
- 扫描远程服务器开放端口
- v-chart 自定义显示格式
- 饥荒联机版连不上服务器_饥荒无法连接klei服务器刷不出服务器解决办法
- 服务器千兆网卡显示百兆,Cisco 2960交换机,服务器千兆网卡,显示百兆问题?...
- Windows Server 2008 R2 组策略基本设置
- Java练习题-09
- c语言图书馆管理程的运行截图,c语言图书管理系统