康拓展开[快速找到某个数在全排序中的位置]

本文介绍了康拓排序的基本原理及其应用,通过实例详细解释了如何利用康拓排序进行全排列数的计算,包括正向和逆向查找过程。此外,还提供了一个具体的C语言实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写了道题,经典的Eight题目,就推数字的问题。
然后里面用到了康拓展开来优化。
后面讲题先来讲康拓展开

刚开始算法练习的时候,最害怕跟全排序有关的问题,因为当时不是很懂递归,也不是很会搜索,就很害怕。。
扯远了。我们来讲康拓排序。

  • 康拓排序

康拓排序更像是当初我们学的数论里面的一个只是点,其实他就是小的全排列和数的相乘法,并不难懂。

先来看个例题,比如给你5个数字1,2,3,4,5;
问你第23个全排列数是多少?
我们来一位一位的考虑
最左边这位,即最高位。他如果从1开始变化,如果它想要增加1,那我们的全排列数要排列多少次呢?很显然4! = 16次。 所以我们先 23 / 4! = 1······7,即我们第一个数字增加了1,而且后面的数字还进行了7次全排列。那么第一个数字是2

第二个数字是什么呢?和第一个数字求取一样 7 / 3! = 1······1, 第二个数字是3
依次类推,第三个数字是1,然后是4, 5.

所以第23个数字就是23145

同理反推,如果给你一个数字23145,怎么算他是第几个

要看每一位数字是这群数字总第几小。
第一位2,后面只有一个1比他小,说明第一位进了一下,这里要加一个4!* 1
第二位3,后面也只有一个1比他小,说明进了一下,这里要加一个3! * 1
依次类推

ans = 4! + 3! + 0! = 23

int cantor(int *arr)
{
    int ans = 0;
    for (int i=0; i<9; i++){
        int t = 0;
        for (int j=i+1; j<9; j++){
            if (arr[j] < arr[i]) t++;
        }
        ans = ans + FAC[9-i-1] * t;
    }
    return ans + 1;
}
//这里 FAC表示一个数组,里面存着从0开始到9的阶乘数
//查表让程序更快

然后最后给出题目,其实有了这个优化,其他部分就是一些数组的转化和普通的bfs。
A-Eight

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值