您的位置:首页 > 其它

Cantor expansion(康托展开)

2015-02-24 19:51 579 查看
定义:

将一个整数X展开为如下形式:

X=a
*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[2]*1!+a[1]*0! (其中,a为整数,并且0<=a[i]<i(1<=i<=n))

全排列的编码:

{1,2,3,4,...,n}的排列总共有n!种,将它们从小到大排序,怎样知道其中一种排列是有序序列中的第几个?
如 {1,2,3,4,5,6,7,8,9} 按从小到大排列一共9!个。想知道357412968是全排列第几个大的数。

答案是:98884。因为X=2*8!+3*7!+4*6!+2*5!+0*4!+0*3!+2*2!+0*1!+0*0!=98884。

解释:排列的第一位是3,比3小的数有两个,所以最高位(第一位)可以是1或者2,而后面有8位,不管是它们什么,反正有8!种排列。(2*8!)

排列的第二位是5,比5小的数有四个,但是3之前出现过,所以第二位可以使1,2或者4,而后面有7位,有7!种排列。(3*7!)

以此类推。。。。。。

全排列的解码:

既然康托展开是一个双射,那么一定可以通过康托展开值求出原排列,即可以求出n的排列中第x小的排列。

如何找出第16个(按字典序的){1,2,3,4,5}的全排列?

答案是:1,4,3,5,2。

解释:

1. 首先用16-1得到15
2. 用15去除4! 得到0余15
3. 用15去除3! 得到2余3

4. 用3去除2! 得到1余1

5. 用1去除1! 得到1余0

有0个数比它小的数是1,所以第一位是1
有2个数比它小的数是3,但1已经在之前出现过了所以是4
有1个数比它小的数是2,但1已经在之前出现过了所以是3
有1个数比它小的数是2,但1,3,4都出现过了所以是5
最后一个数只能是2

所以排列为1,4,3,5,2

题目:http://acm.nyist.net/JudgeOnline/problem.php?pid=139

http://acm.nyist.net/JudgeOnline/problem.php?pid=143
http://acm.hdu.edu.cn/showproblem.php?pid=1430
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: