题目传送门

 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相关推荐

  1. Leetcode46全排列DFS

    链接 题目大意:给定一个数组,求出所有的全排列. 分析 DFS和回溯的方法. 回溯算法的核心 选择列表:表示当前可做的选择 路径:记录做过的选择 结束条件:遍历到树的底层,在这里是选择列表为空的时候. ...

  2. 第七届蓝桥杯决赛真题 - 凑平方数-全排列+dfs+set去重

    题目: 凑平方数 把0~9这10个数字,分成多个组,每个组恰好是一个平方数,这是能够 办到的.比如:0, 36, 5948721再比如: 1098524736 1, 25, 6390784 0, 4, ...

  3. 全排列 DFS 回溯

    //dfs全排列 #include<stdio.h> #include <string.h> char temp[5] = {'A','B','C','D'};//seed c ...

  4. Trie树 + DFS - CSU 1457 Boggle

    Boggle Problem's Link:  http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1457 Mean: 给定n个串,有m个询问. 每个询 ...

  5. 全排列—dfs(递归算法手动模拟)

    目录 1.dfs全排列深度优先算法思路导图 2.dfs递归思想 3.主旨展现 4.详解手动模拟 5.例题来喽 5.1例题(1)来喽 5.2例题(2)来喽 5.3例题(3)来喽 1.dfs全排列深度优先 ...

  6. 全排列(dfs、小白、详细解释)

    目录 主函数 用来排序的函数 详细过程 代码 从键盘输入一个没有重复元素的字符串,输出这个字符串所有字符的全排列 输入格式: 一个字符串,输入保证字符串中没有重复的字符,字符串的长度不超过10,字符串 ...

  7. wikioi 1294 全排列 dfs

    1294 全排列 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 给出一个n, 请输出n的所有全排列 输入描述 Input Desc ...

  8. [Leetcode][第60题][JAVA][第k个排列][回溯][DFS][剪枝]

    [问题描述][中等] [解答思路] 1. 回溯搜索算法 + 剪枝 ,直接来到叶子结点 时间复杂度:O(N^2) 空间复杂度:O(N) import java.util.Arrays;public cl ...

  9. 【算法】蓝桥杯dfs深度优先搜索之排列组合总结

    [导航] 上一篇文章 → <[算法]蓝桥杯dfs深度优先搜索之凑算式总结>   为了重申感谢之意,再次声明下文的大部分灵感均来自于[CSDN]梅森上校<JAVA版本:DFS算法题解两 ...

最新文章

  1. Go 学习笔记(18)— 函数(04)[闭包定义、闭包修改变量、闭包记忆效应、闭包实现生成器、闭包复制原对象指针]
  2. 派生类的继承方式【C++继承】
  3. Linux设备驱动归纳总结(一):内核的相关基础概念
  4. 设计模式之Builder (创建者模式)的一些个人理解(转)
  5. Python编程从入门到实践~字典
  6. ERROR: Failed building wheel for pycrypto
  7. 在CLR中自动本地化正在运行的.NET窗口
  8. 4月17日 键盘大小写指示indicator-lockkeys
  9. Photoshop CS6下载包下载 及破解安装教程
  10. 黑客是如何入侵网站?为什么企业网站需要渗透测试?
  11. pixi 小游戏_学习如何用pixi.js开发微信小游戏
  12. 最保险的“跳槽理由”
  13. 20220313_朴素贝叶斯
  14. 扫描远程服务器开放端口
  15. v-chart 自定义显示格式
  16. 饥荒联机版连不上服务器_饥荒无法连接klei服务器刷不出服务器解决办法
  17. 服务器千兆网卡显示百兆,Cisco 2960交换机,服务器千兆网卡,显示百兆问题?...
  18. Windows Server 2008 R2 组策略基本设置
  19. Java练习题-09
  20. c语言图书馆管理程的运行截图,c语言图书管理系统

热门文章

  1. Quartus使用技巧(一些常用的方法)
  2. 解决pycharm输入法不跟随的方法
  3. 第130天:移动端-rem布局
  4. scrapy-splash抓取动态数据例子八
  5. flex 3 使用手册
  6. 截图推荐:FastStone Capture使用教程
  7. swfupload--php上传说明
  8. Request.UrlReferrer详解
  9. 浅析Microsoft .net PetShop程序中的购物车和订单处理模块(Profile技术,异步MSMQ消息)转...
  10. 好大一盘棋:谷歌光纤再下一城