组合数学(全排列)+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]中,粉红色所示部分就是 ...
随机推荐
- Hadoop日记Day1---Hadoop介绍
一.Hadoop项目简介 1. Hadoop是什么 Hadoop是一个适合大数据的分布式存储与计算平台. 作者:Doug Cutting:Lucene,Nutch. 受Google三篇论文的启发 2. ...
- 如何下载google play免费应用的apk文件
到这里: http://apps.evozi.com/apk-downloader/ 一看便知.
- vi命令的基础知识
vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,先说说一下它的用法和一小部分指令.由于对Unix及Linux系统的任何版本,vi编辑器是完全相同的,因此您 ...
- bootbox显示中文的按钮
$("selector").on('click',function(){ bootbox.confirm({ title : "请确认", buttons: { ...
- IE8 不支持html5 placeholder的解决方案
IE8不支持html5 placeholder的解决方法. /** * jQuery EnPlaceholder plug * version 1.0 2014.07.01戈志刚 * by Frans ...
- Cocos2d-JS坐标系统
标准屏幕坐标系 如果接触过iOS,Android,Windows Phone等系统的应用开发,或使用DOM,CSS开发过Web网页,开发者会非常熟悉所谓的标准屏幕坐标系:左上角为原点,向右为X轴正方向 ...
- [Android Pro] RecyclerView实现瀑布流效果(二)
referece to : http://blog.csdn.net/u010687392 在上篇中我们知道RecyclerView中默认给我们提供了三种布局管理器,分别是LinearLayoutMa ...
- VelocityTracker简介
android.view.VelocityTracker主要用跟踪触摸屏事件(flinging事件和其他gestures手势事件)的速率.用addMovement(MotionEvent)函数将Mot ...
- iphone越狱还原
在Cydia 里安装Impactor 就行了 .在操作时需要全程联网: .请至少保证 % 的电量以防止在恢复过程出现断电的情况(建议将设备连接至电源): .设备将恢复至出厂状态,所有用户数据都将被清除 ...
- ligureUI 刷新列求和
dataGrid=$("#dataGrid").ligerGrid({ columns: [ {display:, align:'left' }, {display:, align ...