组合数学(全排列)+DFS CSU 1563 Lexicography
/*
题意:求第K个全排列
组合数学:首先,使用next_permutation 函数会超时,思路应该转变,
摘抄网上的解法如下:
假设第一位是a,不论a是什么数,axxxxxxxx一共有8!种选择。
297192 div 8! = 7,余14952,所以第一位是1-9中的第8个数,也就是8。
14952 div 7! = 2,余4872,所以第二位是3。
4872 div 6! = 6,余552,所以是第三位是1245679这七个数中的第7个,也就是 9。
552 div 5! = 4,余72,所以是124567中的第5个,也就是6。
72 div 4! = 2,余24,所以是4。
这时候就不用算了,因为24 = 4!,而剩下的数就是1257这4个,他们组成的排列的第
24个必然是7521。
以上解法只符合没有重复的序列,但是思路一致,把除法改为减法,每一次更新之后的全排列的数量
即 Ann / Amm 的个数,可以用DFS实现
*/
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <stack>
#include <cmath>
#include <cstring>
#include <vector>
using namespace std; const int MAXN = 1e4 + ;
const int INF = 0x3f3f3f3f;
char s[];
int cnt[];
int pos[];
int len; long long fact(int x)
{
long long res = ;
for (int i=; i<=x; ++i) res *= i; return res;
} long long f(int step)
{
long long res = fact (step);
for (int i=; i<; ++i) if (cnt[i]) res /= fact (cnt[i]); return res;
} void DFS(int step, long long k)
{
if (step == len)
{
for (int i=; i<len; ++i) printf ("%c", 'A' + pos[i]);
puts (""); return ;
} for (int i=; i<; ++i)
{
if (cnt[i] == ) continue;
cnt[i]--;
long long tmp = f (len - step - );
if (tmp < k) {k -= tmp; cnt[i]++;}
else
{
pos[step] = i;
DFS (step+, k);
return ;
}
}
} int main(void) //CSU 1563 Lexicography
{
//freopen ("C.in", "r", stdin); long long k;
while (scanf ("%s%lld", &s, &k) == )
{
if (s[] == '#' && k == ) break; len = strlen (s);
memset (pos, , sizeof (pos));
memset (cnt, , sizeof (cnt));
for (int i=; i<len; ++i) cnt[s[i]-'A']++; DFS (, k);
} return ;
} /*
MAC
PICC
IGNORE
*/
附带给出求1~9无重复数字的第K个全排列的两种方法
/*
假设第一位是a,不论a是什么数,axxxxxxxx一共有8!种选择。
297192 div 8! = 7,余14952,所以第一位是1-9中的第8个数,也就是8。
14952 div 7! = 2,余4872,所以第二位是3。
4872 div 6! = 6,余552,所以是第三位是1245679这七个数中的第7个,也就是 9。
552 div 5! = 4,余72,所以是124567中的第5个,也就是6。
72 div 4! = 2,余24,所以是4。
这时候就不用算了,因为24 = 4!,而剩下的数就是1257这4个,他们组成的排列的第
24个必然是7521。
*/
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <stack>
#include <cmath>
#include <cstring>
#include <vector>
using namespace std; const int MAXN = 1e4 + ;
const int INF = 0x3f3f3f3f;
int num[];
int ans[];
int f[]; int main(void)
{
//freopen ("test_C.in", "r", stdin); int k;
while (scanf ("%d", &k) == )
{
f[] = ;
for (int i=; i<=; ++i) {f[i] = f[i-] * i; num[i] = i;} int tot = ;
int len = ;
bool flag = false;
while (tot < len)
{
int pos = k / f[len-tot-] + ;
k %= f[len-tot-]; if (k == ) {pos--; flag = true;} int t = ;
for (int i=; i<=; ++i)
{
if (num[i] != )
{
++t;
if (t == pos)
{
printf ("%d", num[i]);
tot++; num[i] = ; break;
}
}
} if (flag)
{
for (int i=; i>=; --i)
{
if (num[i] != ) printf ("%d", num[i]);
}
break;
}
}
puts ("");
}
return ;
} /*
839647521
*/
1. 用上面的思路
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <stack>
#include <cmath>
#include <cstring>
#include <vector>
using namespace std; const int MAXN = 1e4 + ;
const int INF = 0x3f3f3f3f;
int num[];
int ans[];
int f[]; int main(void)
{
//freopen ("test_C.in", "r", stdin); int k;
while (scanf ("%d", &k) == )
{
for (int i=; i<=; ++i) num[i] = i; int len = ;
long long cnt = ;
do{
++cnt;
if (cnt == k) break;
}while (next_permutation (num+, num++len)); for (int i=; i<=; ++i)
printf ("%d", num[i]);
puts ("");
}
return ;
} /*
839647521
*/
2. 用next_permutation函数
组合数学(全排列)+DFS CSU 1563 Lexicography的更多相关文章
- csu 1563 Lexicography
题意:给出一堆字母 问这些字母组成的字符串中第k大的 排列组合,具体看代码 //寒假集训被何柱大大踩好惨(>_<) #include<cstdio> #include<i ...
- for循环枚举法,全排列+dfs,补充浮点数注意事项
其实这个题目我一直没想好应该叫什么,就是在做蓝桥杯的时候会遇到很多的题,给你一等式,abcdef...分别是1-9(||12||15)不重复问你有几种方案? 我之前一直都是用的for循环在做,听说这叫 ...
- 数的全排列 dfs深度优先搜索
数的全排列. 输入格式: 一个n(n<10),表示长度 输出格式: 按字典序输出长度为n的所有排列,每个排列后需要换行,每个排列数字以空格分开. 输入样例: 在这里给出一组输入.例如: 3 输出 ...
- uva 10344 23 out of 5 凑运算结果 全排列+dfs
五个数三个运算符号,排列之后凑成结果为23,不考虑优先级. 很水,数据量也不大,先生成五个数的全排列,用dfs找出结果能否为23即可. 代码: #include <cstdio> #inc ...
- Trie树 + DFS - CSU 1457 Boggle
Boggle Problem's Link: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1457 Mean: 给定n个串,有m个询问. 每个询问 ...
- 全排列——DFS实现
原创 之间就写过一篇全排列的博客:https://www.cnblogs.com/chiweiming/p/8727164.html 详细介绍请回看,用的方法(暂且就叫)是“交换法”,其实思路就是DF ...
- zzulioj--1730--通信基站(全排列+dfs)(好题)
1730: 通信基站 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 28 Solved: 11 SubmitStatusWeb Board Desc ...
- 全排列dfs算法
如下 #include <iostream> using namespace std; #define MAX 10 #define _CRT_SECURE_NO_WARNINGS int ...
- 蓝桥杯 剪邮票 全排列+DFS
剪邮票 如[图1.jpg], 有12张连在一起的12生肖的邮票. 现在你要从中剪下5张来,要求必须是连着的. (仅仅连接一个角不算相连) 比如,[图2.jpg],[图3.jpg]中,粉红色所示部分就是 ...
随机推荐
- 裸设备和Oracle问答20例
导读裸设备,也叫裸分区(原始分区),是一种没有经过格式化,不被Unix通过文件系统来读取的特殊字符设备.裸设备可以绑定一个分区,也可以绑定一个磁盘.本文收集裸设备和Oracle问答20例. 1.什么叫 ...
- 从零开始写一个武侠冒险游戏-7-用GPU提升性能(2)
从零开始写一个武侠冒险游戏-7-用GPU提升性能(2) ----把地图处理放在GPU上 作者:FreeBlues 修订记录 2016.06.21 初稿完成. 2016.08.06 增加对 XCode ...
- ubuntu14.04中国源
deb http://cn.archive.ubuntu.com/ubuntu/ trusty main restricted universe multiverse deb http://cn.ar ...
- .NET Reflector 7.6.1.824 Edition .NET程序反编译神器(附插件安装教程2012-10-13更新) 完全破解+使用教程
原文来自VAllen cnblogs 一.使用教程1.解压后,双击Reflector.exe,如果有选择默认版本的.Net Framework,根据需要选择即可.你选择的版本不同则出现的默认程序集也不 ...
- ARM 处理器的几个相关术语
生产ARM的厂商很多,自然ARM处理器的名字就五花八门.但是,它们有些共同点,那就是:架构和核心. 架构这个概念太宽不太懂,一般不同的架构会有不同的指令集,在不同的架构下面还可以有多种核心.核心就是指 ...
- Java for LeetCode 146 LRU Cache 【HARD】
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
- CodeForces - 405C
Unusual Product Time Limit: 1000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u Sub ...
- loadingDialog
1.dialog布局 dialog_loading.xml <?xml version="1.0" encoding="utf-8"?> <L ...
- 配置无线网络的时候会提示“Enter Password for Default Keyring to Unlock”
密钥管理软件Seahorse有关,这个时候我们打开c配置一下就可以解决. 命令行下运行seahorse或依次点击菜单“应用程序→附件→密码和加密密钥”, 在login一行中右键选择更改密码,然后什么都 ...
- navicat使用跳板机连接数据库-ssh
1. 目标数据库的域名/IP,端口,用户名,密码:如图1 2. 这时候不要点OK!选择SSH这个tab 3. 选中User SSH Tunnel:填写跳板机域名/IP,用户名,密码(注意:端口22不要 ...