编程题:康托展开
康托展开是1~n的一个全排列到一个自然数的映射。例如: 对于 1 ~ 4 的一个全排列 1234 和 4321,我们知道,从字典序而言,前者是该全排列集的第一个,后者是该集的最后一个。那么,所谓康托展开,即给定一个 n 位数的全排列,我们可以根据康托展开公式确定其应当是字典序中的第几个全排列。康托展开常用于构建哈希表时的空间压缩,例如,检查一个1~8的全排列是否出现过,我们可以开一个数组进行标识,如不压缩,需要开的空间大小为1e8左右(上百兆的空间),而压缩后,8!= 40320,所开空间不到5万(不足1兆)。
给定一个全排列,计算其字典序。直观起见,我们举例2341来说明康托展开的运作步骤:
第 1 位是 2, 那么以 1 打头的所有全排列一定排在这个全排列之前,那么以 1 打头的全排列有 (3!) = 6个。
第 2 位是 3,那么以 1 与 2 作为第二位的所有全排列一定在这个圈排列之前。不过我们已经让 2 打头了,因此不需要再考虑 2 占第二位的情况,只需要计算 1 占第二位的情况。1∗2!=2个。
第三位是 4,同时,我们计算以 1 占第三位的所有情况。1∗1!=1个。
最后一位,是不需要判定的,因为前 n−1 位给定后,第 n位自定。
因此,有6+2+1=9个全排列比2341小,即2341是第10个全排列,如从0开始编号,2341的序号为9。
### 输入格式:
一个1~n的全排列。
### 输出格式:
该全排列的序号(序号从0开始编号,即对于123编号为0,321编号为5)。
### 输入样例:
in
321
### 输出样例:
out
5
答案:若无答案欢迎评论
给定一个全排列,计算其字典序。直观起见,我们举例2341来说明康托展开的运作步骤:
第 1 位是 2, 那么以 1 打头的所有全排列一定排在这个全排列之前,那么以 1 打头的全排列有 (3!) = 6个。
第 2 位是 3,那么以 1 与 2 作为第二位的所有全排列一定在这个圈排列之前。不过我们已经让 2 打头了,因此不需要再考虑 2 占第二位的情况,只需要计算 1 占第二位的情况。1∗2!=2个。
第三位是 4,同时,我们计算以 1 占第三位的所有情况。1∗1!=1个。
最后一位,是不需要判定的,因为前 n−1 位给定后,第 n位自定。
因此,有6+2+1=9个全排列比2341小,即2341是第10个全排列,如从0开始编号,2341的序号为9。
### 输入格式:
一个1~n的全排列。
### 输出格式:
该全排列的序号(序号从0开始编号,即对于123编号为0,321编号为5)。
### 输入样例:
in
321
### 输出样例:
out
5
答案:若无答案欢迎评论