算法:康托展开
分析:康托展开只看了一点,具体来说就是根据数求序或根据序求数。
例如要求321是第几大的数,考虑第一位,因为第一位是3,小于3的数有1,2。所以有2×2!个。
再看第二位是2,小于2的数只有1个就是1,所以有1×1!,所以小于321的{1,2,3}排列数有2×2!+1*1!=5个。
再举个例子:1324是{1,2,3,4}排列数中第几个大的数:
第一位是1小于1的数没有,是0个 0*3!。
第二位是3小于3的数有1和2,但1已经在第一位了,所以只有一个数2 1*2!。
第三位是2小于2的数是1,但1在第一位,所以有0个数 0*1!。
分析:康托展开只看了一点,具体来说就是根据数求序或根据序求数。
例如要求321是第几大的数,考虑第一位,因为第一位是3,小于3的数有1,2。所以有2×2!个。
再看第二位是2,小于2的数只有1个就是1,所以有1×1!,所以小于321的{1,2,3}排列数有2×2!+1*1!=5个。
再举个例子:1324是{1,2,3,4}排列数中第几个大的数:
第一位是1小于1的数没有,是0个 0*3!。
第二位是3小于3的数有1和2,但1已经在第一位了,所以只有一个数2 1*2!。
第三位是2小于2的数是1,但1在第一位,所以有0个数 0*1!。
所以比1324小的排列有0*3!+1*2!+0*1!=2个,1324是第三个大数。
PROGRAM KIMBITS;
CONST
MAXN=31;
VAR
N,L,I,J:LONGINT;
M:INT64;
F:ARRAY [0..MAXN,0..MAXN] OF LONGINT;
BEGIN
ASSIGN(INPUT,'kimbits.in'); RESET(INPUT);
ASSIGN(OUTPUT,'kimbits.out'); REWRITE(OUTPUT);
READLN(N,L,M);
FOR I:=0 TO N DO
BEGIN
F[I,0]:=1;
F[0,I]:=1;
END;
FOR I:=1 TO N DO FOR J:=1 TO L DO F[I,J]:=F[I-1,J]+F[I-1,J-1];
FOR I:=N-1 DOWNTO 0 DO
BEGIN
IF F[I,L]<M THEN
BEGIN
WRITE('1');
DEC(M,F[I,L]);
DEC(L);
END
ELSE WRITE('0');
END;
WRITELN;
CLOSE(INPUT); CLOSE(OUTPUT);
END.