排列序数
X星系的某次考古活动发现了史前智能痕迹。
这是一些用来计数的符号,经过分析它的计数规律如下:
(为了表示方便,我们把这些奇怪的符号用a~q代替)
abcdefghijklmnopq 表示0
abcdefghijklmnoqp 表示1
abcdefghijklmnpoq 表示2
abcdefghijklmnpqo 表示3
abcdefghijklmnqop 表示4
abcdefghijklmnqpo 表示5
abcdefghijklmonpq 表示6
abcdefghijklmonqp 表示7
.....
在一处石头上刻的符号是:
bckfqlajhemgiodnp
请你计算出它表示的数字是多少?
请提交该整数,不要填写任何多余的内容,比如说明或注释。
这道题用康托展开式写比较简单,不过首先还是要先理解什么是康托展开式。
康托展开式:
X=an*(n-1)!+an-1*(n-2)!+…+ai*(i-1)!+…+a2*1!+a1*0!
这个式子是由1到n这n个数组成的全排列,共n!个,按每个全排列组成的数从小到大进行排列,并对每个序列进行编号(从0开始),并记为X。
比如说1到4组成的全排列中,长度为4,1234对应编号0,1243对应编号1
那a1,a2,a3,a4是什么意思呢?==>>
对1到4的全排列中,我们来考察3214,则
-
a4={3在集合(3,2,1,4)中是第几大的元素}=2
-
a3={2在集合(2,1,4)中是第几大的元素}=1
-
a2={1在集合(1,4)中是第几大的元素}=0
-
a1=0(最后只剩下一项)
则X=2*3!+1*2!+0*1!+0*0!=14,即3214对应的编号为14。
因此,此题用康托展开式就可以出来了,将abcd…写成1,2,3,4…就行了。
PS:以上这段解释是来自 JuLi距离的,我也是看他这段话才理解了康托展开式。
代码:
public class Main {
/**
* 阶乘方法
* @param n
* @return
*/
public static long jiecheng(int n) {
if (n == 1) {
return 1;
}
return n * jiecheng(n - 1);
}
public static void main(String[] args) {
int[] a = { 2, 3, 11, 6, 17, 12, 1, 10, 8, 5, 13, 7, 9, 15, 4, 14, 16 };
long sum = 0;
for (int i = 0; i < 16; i++) {
for (int j = i + 1; j < 17; j++) {
int t = 0;
if (a[i] > a[j]) {//求康托展开式中an的大小
t++;
}
sum += t * jiecheng(17 - 1 - i);//康托展开式
}
}
System.out.println(sum);
}
}
ps:注意阶乘返回值和问题的结果都要用long型。
答案:22952601027516