用康托展开实现全排列(STL、itertools)
康拓展开:
$X=a_n*(n-1)!+a_{n-1}*(n-2)!+\ldots +a_2*1!+a_1*0!$
X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! 其中,a为整数,并且0<=ai<i(1<=i<=n)
这个式子就是康托展开,初看同排列没什么关系,实则不然。下面通过举个例子看一下
一、用康托展开判断一个排列是第几小的
以{1,2,3}为例。我们定义排列的顺序从小到大为123,132,213,231,312,321。
然后我们随便给一个比如312,要判断他在排列中第几大的,则我们可以这样思考,首先第一个比3小可以是1或2,则有2*2!中,第二位比1小,没有,第三位没有。如果说这个不够明显我们看一下321是第几个,首先比3小的2*2!,比2小的1*1!,共2*2!+1*1!=6,。至于其他的各位有兴趣也可以去计算。但这不是我们的重点,我们的重点是得到全排列。
二、康托逆展开
既然康托展开可以判断出某个组合是第几个,那么他是不是也可以构造出第几个排列的值呢?答案是可以的,这里我们叫做康托逆展开。同样的举个例子来看他的工作过程。还是{1,2,3}。现在我们要求出第四大的排列,首先(4-1)%2!=1余1,这个结果表示有有1个数比他小的是2,也就是排列的第一位是2,然后1-1=0则表示没有比第二个大的,即第二个为3,故231。其他例子各位可以自己试。这里给出C++的实现代码
int fac[]={,,,,,,,};
int* cantor(int m,int n)//m is for the size of the set,n is the sequence number
{
bool flag[]={false};
int *ans=new int[];
int i=m;
int j=n-;
while(i--)
{
int temp=(j)/fac[i]+;
int count=-,t;
for(t=;t<m;t++)
{
if(!flag[t])
count++;
if(temp==count)
break;
}
ans[m-i-]=t;
flag[t]=true;
j=(j)%fac[i];
}
//for(int t=0;t<m;t++)
//cout<<ans[t];
//cout<<endl;
return ans;
}
不过写完之后突然发现STL中有实现全排列的函数叫
next_permutation()
有兴趣可以看看
--------------------------------------------------python-----------------------------------------------------------
使用python的话也有一个相应的库iteltools,可以实现排列组合
使用方法见代码
>>>import itertools
>>>list(itertools.permutations([1,2,3,4],4))
[(1, 2, 3, 4), (1, 2, 4, 3), (1, 3, 2, 4), (1, 3, 4, 2), (1, 4, 2, 3), (1, 4, 3, 2), (2, 1, 3, 4), (2, 1, 4, 3), (2, 3, 1, 4), (2, 3, 4, 1), (2, 4, 1, 3), (2, 4, 3, 1), (3, 1, 2, 4), (3, 1, 4, 2), (3, 2, 1, 4), (3, 2, 4, 1), (3, 4, 1, 2), (3, 4, 2, 1), (4, 1, 2, 3), (4, 1, 3, 2), (4, 2, 1, 3), (4, 2, 3, 1), (4, 3, 1, 2), (4, 3, 2, 1)]
>>>list(itertools.combinations([1,2,3,4],4))
[(1, 2, 3, 4)]
用康托展开实现全排列(STL、itertools)的更多相关文章
- OJ 1188 全排列---康托展开
题目描述 求n的从小到大第m个全排列(n≤20). 输入 n和m 输出 输出第m个全排列,两个数之间有一空格. 样例输入 3 2 样例输出 1 3 2 #include<cstdio> # ...
- P3014 [USACO11FEB]牛线Cow Line && 康托展开
康托展开 康托展开为全排列到一个自然数的映射, 空间压缩效率很高. 简单来说, 康托展开就是一个全排列在所有此序列全排列字典序中的第 \(k\) 大, 这个 \(k\) 即是次全排列的康托展开. 康托 ...
- LightOJ1060 nth Permutation(不重复全排列+逆康托展开)
一年多前遇到差不多的题目http://acm.fafu.edu.cn/problem.php?id=1427. 一开始我还用搜索..后来那时意外找到一个不重复全排列的计算公式:M!/(N1!*N2!* ...
- 康托展开:对全排列的HASH和还原,判断搜索中的某个排列是否出现过
题目:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2297 前置技能:(千万注意是 ...
- [洛谷P3014][USACO11FEB]牛线Cow Line (康托展开)(数论)
如果在阅读本文之前对于康托展开没有了解的同学请戳一下这里: 简陋的博客 百度百科 题目描述 N(1<=N<=20)头牛,编号为1...N,正在与FJ玩一个疯狂的游戏.奶牛会排成一行 ...
- UVA11525 Permutation[康托展开 树状数组求第k小值]
UVA - 11525 Permutation 题意:输出1~n的所有排列,字典序大小第∑k1Si∗(K−i)!个 学了好多知识 1.康托展开 X=a[n]*(n-1)!+a[n-1]*(n-2)!+ ...
- leetcode 60. Permutation Sequence(康托展开)
描述: The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of t ...
- NYOJ--139--我排第几个(康托展开)
我排第几个 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 现在有"abcdefghijkl"12个字符,将其所有的排列中按字典序排列,给出任意一 ...
- 康托展开&&康托逆展开
康托展开 简介:对于给定的一个排列,求它是第几个,比如54321是n=5时的第120个.(对于不是1~n的排列可以离散化理解) 做法: ans=a[n]*(n-1)!+a[n-1]*(n-2)!+~~ ...
随机推荐
- HIFI播放器--磨机吐槽篇
最近看到淘宝店提供各种随身播放器磨机服务,说的是天花乱坠,给你更换零件, 甚至更改电路,搭载上去,是如何如何的好,整个播放器就上升了几个等次,收费还 不低,至少是好几百,我实在是忍不住吐槽了,你们这些 ...
- 音频DAC剖析---解开HI-FI音质的秘密
选自:http://mp3.zol.com.cn/54/547689.html 无论我们是买MP3.MP4也好,实际上我们的数码播放器最经常使用的就是音乐播放功能,所以数码播放器的音质,一直是消费者的 ...
- phpcms中action值的含义
action值的含义:lists 内容数据(文章?)列表relation 内容相关文章hits 内容数据点击排行榜category 内容栏目列表position 内容推荐位列表
- Docker与LXC的区别
转自: http://blog.csdn.net/wangtaoking1/article/details/45043523 Docker并不是LXC的替代品,Docker的底层就是使用了LXC来实现 ...
- gcc-5.4.0 static dwarf2 compile
------------------------------------------------------------------------------- 又开始折腾了, 静态编译 gcc-5.4 ...
- centos搭建svn服务器并在windows实验
安装步骤如下: 1.yum install subversion 2.输入rpm -ql subversion查看安装位置,如下图: 我们知道svn在bin目录下生成了几个二进制文件. 输入 ...
- iOS9 UI Tests探索笔记
UI Tests是什么? UI Tests是一个自动测试UI与交互的Testing组件 UI Tests有什么用? 它可以通过编写代码.或者是记录开发者的操作过程并代码化,来实现自动点击某个按钮.视图 ...
- 【leetcode】Valid Sudoku (easy)
题目:就是判断已有的数字是否冲突无效,若无效返回flase 有效返回true 不要求sudo可解 用了char型的数字,并且空格用‘.'来表示的. 思路:只要分别判断横向 竖向 3*3小块中的数字是否 ...
- LINQ查询返回DataTable类型
个人感觉Linq实用灵活性很大,参考一篇大牛的文章LINQ查询返回DataTable类型 http://xuzhihong1987.blog.163.com/blog/static/267315872 ...
- 51nod 1099 任务执行顺序 (贪心算法)
题目:传送门. 题意:中文题. 题解:r[i]-o[i]值大的先进行.反证法:如果大的后进行,会导致空间增大,所以一定大的是先进行. #include <iostream> #includ ...