pku1833 排列
给一个n个数的排列,求其向后k个的排列。
这里有一种字典序模拟法。
1:找到最靠后的x,使a[x]<a[x+1]
2:找到最小的a[y],使a[y]>a[x]
3:交换a[x],a[y]
4:把序列(x+1..n)翻转。
每进行一次上述过程,就向下推了一个排列。
View Code
1 program pku1833(input,output);
2 var
3 a : array[0..2000] of longint;
4 n : longint;
5 k : longint;
6 cases : longint;
7 procedure init;
8 var
9 i : longint;
10 begin
11 fillchar(a,sizeof(a),0);
12 readln(n,k);
13 for i:=1 to n do
14 read(a[i]);
15 readln;
16 end; { init }
17 procedure swap(var aa,bb :longint );
18 var
19 tt : longint;
20 begin
21 tt:=aa;
22 aa:=bb;
23 bb:=tt;
24 end; { swap }
25 procedure main;
26 var
27 i : longint;
28 x,y : longint;
29 begin
30 while k>0 do
31 begin
32 dec(k);
33 i:=n;
34 while (i>0)and(a[i]>a[i+1]) do
35 dec(i);
36 x:=i;
37 if i=0 then
38 begin
39 for i:=1 to n do
40 a[i]:=i;
41 end
42 else
43 begin
44 a[0]:=maxint;
45 y:=0;
46 for i:=x+1 to n do
47 if (a[i]>a[x])and(a[i]<a[y]) then
48 y:=i;
49 swap(a[x],a[y]);
50 for i:=1 to (n-x)>>1 do
51 swap(a[x+i],a[n-i+1]);
52 end;
53 end;
54 end; { main }
55 procedure print;
56 var
57 i : longint;
58 begin
59 for i:=1 to n-1 do
60 write(a[i],' ');
61 writeln(a[n]);
62 end; { print }
63 begin
64 readln(cases);
65 while cases>0 do
66 begin
67 dec(cases);
68 init;
69 main;
70 print;
71 end;
72 end.