写了道题,经典的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