组合数学(全排列)+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]中,粉红色所示部分就是 ...
随机推荐
- [BZOJ1177][Apio2009]Oil
[BZOJ1177][Apio2009]Oil 试题描述 采油区域 Siruseri政府决定将石油资源丰富的Navalur省的土地拍卖给私人承包商以建立油井.被拍卖的整块土地为一个矩形区域,被划分为M ...
- ZeroMQ(java)之Router与Dealer运行原理
在开始这部分的内容之前,先来看看ZeroMQ中HWM概念---High-Water Marks 当系统的数据量很大,而且发送频率很高的情况下,内存就很重要了,如果处理不好会出现很多问题,例如如下场景: ...
- linux shell expr 使用
linux shell expr 使用 收藏人:春秋百味 -- | 阅: 转: | | 分享 非原创, 摘自:<LINUX与UNIX Shell编程指南> 17.5 expr用法 expr ...
- 腾讯新浪通过IP地址获取当前地理位置(省份)的接口
腾讯新浪通过IP地址获取当前地理位置(省份)的接口 腾讯的接口是 ,返回数组 http://fw.qq.com/ipaddress 返回值 var IPData = new Array(" ...
- PHP 遍历目录
$dir = $_SERVER['DOCUMENT_ROOT'].'/test'; //var_dump($dir);exit; function my_scandir($dir) { $files ...
- 如何使用setup.py文件
setup.py文件的使用:% python setup.py build #编译% python setup.py install #安装% python setup.py sdist ...
- Nested List Weight Sum I & II
Nested List Weight Sum I Given a nested list of integers, return the sum of all integers in the list ...
- object-c 基本数据类型
1.基本数据类型 int float double char 布尔类型 枚举类型 2.对象类型和id类型 就是类类型或协议所声明的指针类型. id类型可以表示任何类型,一般只表示 ...
- su成别的用户后仍以原来私钥访问远程机器
背景: 同步机和游戏服两台机都有个人用户账号和游戏账号xy1,游戏服设了xy1的ssh强制命令来受同步机的xy1控制.现在需要在同步机上用xy1进行一个控制游戏服的操作,该操作需要在同步机远程tail ...
- 百度编辑器ueditor每次编辑后多一个空行的解决办法
用ueditor进行编辑文章时,每次编辑后文章前面都会多出一个空行. <script id="editor" type="text/plain" styl ...