组合数学(全排列)+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]中,粉红色所示部分就是 ...
随机推荐
- (11)UI布局和分辨率适配
一.Cocos编辑器 自动布局系统主要涉及固定与拉伸属性: 如图,总共可以修改控件的上下左右四个图钉和中间的两个拉伸条六个属性. 效果 1.当打开其中的任意一个图钉时,当前节点与父节点的对应边 ...
- XSS的DOS攻击之 server limit dos
墨西哥同学周末很郁闷的在宾馆上网,发现youtube被ban了,于是写个了tool解决这个问题.顺带想到了一种利用 google 统计的漏洞,写在这里了 http://sirdarckcat.blog ...
- jsp 学习 第3步 - el 自定义方法 tld 说明
使用 el 的过程中,需要使用到后端代码处理逻辑,这个时候我们就需要自定义 方法. 如我们后端代码定义如下: package com.rhythmk.common; public class FncH ...
- HDU 4883 TIANKENG’s restaurant
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4883 解题报告:一家餐馆一天中有n波客人来吃饭,第 i 波 k 客人到达的时间是 s ,离开时的时间 ...
- C++中的vector使用范例
原文链接 http://blog.csdn.net/tjh666/article/details/1604119 1.vector 的数据的存入和输出: #include<stdio.h> ...
- 菜鸟带你飞______DP基础26道水题
DP 158:11:22 1205:00:00 Overview Problem Status Rank (56) Discuss Current Time: 2015-11-26 19:11:2 ...
- Linux tar命令exclude选项排除指定文件或目录
在linux中可以用tar打包目录以方便传输or备份,我们先来看一个例子 test 文件夹有如下文件 [root@lee ~]# ll test 总用量 -rw-r--r--. root root 4 ...
- 在 FREEBUF 投放广告
在 FREEBUF 投放广告 FreebuF黑客与极客—高质量的全球互联网安全媒体,同时也是爱好者们交流.分享安全技术的最佳平台.本站读者群以IT.政企信息安全人员.互联网安全爱好者和学生为主,对互联 ...
- RPM软件包管理的查询功能
以后大家升级rpm包的时候,不要用Uvh了! 我推荐用Fvh 前者会把没有安装过得包也给装上,后者只会更新已经安装的包 总结:未安装的加上小写p,已安装的不需要加p 查询q rpm {- ...
- nc 常用命令
nc(NetCat),在网络工具中有”瑞士军刀”的美誉,它短小精悍,功能强大,下面分享一些我平时经常用到的功能,更多的功能请google之. 1.基本参数想要连接到某处: nc [-options] ...