BZOJ1081:[SCOI2005]超级格雷码
Description
著名的格雷码是指2n个不同n位二进制数(即0~2n-1,不足n位在前补零)的一个排列,这个排列满足相邻的两
个二进制数的n位数字中最多只有一个数字不同(例如003和001就有一个数位不同,而003和030有两个数位不同,
不符合条件)。例如n=2时,(00,01,11,10)就是一个满足条件的格雷码。 所谓超级格雷码就是指Bn个不同的n位B
进制数的排列满足上面的条件。 任务:给出n和B(2≤B≤36, 1≤Bn≤65535),求一个满足条件的格雷码。对于
大于9的数位用A~Z表示(10~35)。
Input
只有一行,为两个整数n和B。
Output
一共Bn个行,每行一个B进制数,表示你所求得的符合条件的排列
Sample Input
2 2
Sample Output
00
01
11
10
01
11
10
题解:
身为一道构造题竟然没有SPJ,辣鸡BZOJ。
给每一位设置一个增减标记,1表示增,-1表示减。
求下一个格雷码时,从第一位开始访问,若还能根据其增减标记改变,则增1或减1,并输出答案;若不能,则改变其增减标记,去访问下一位。
辣鸡BZ,数据与给出样例不符。
代码:
1 const 2 f:array[0..1]of longint=(1,-1); 3 var 4 i,j,k,l,n,nn,m:longint; 5 a,b:array[0..100]of longint; 6 function x(a:longint):char; 7 begin 8 if a<10 then exit(chr(a+ord('0'))); 9 exit(chr(a-10+ord('A'))); 10 end; 11 begin 12 readln(m,n); 13 for i:=1 to m do write(0); writeln; 14 nn:=1; 15 for i:=1 to m do nn:=nn*n; nn:=nn-1; 16 for i:=1 to nn do 17 begin 18 j:=m; 19 while(a[j]+f[b[j]]>n-1)or(a[j]+f[b[j]]<0)do 20 begin b[j]:=1-b[j]; dec(j); end; 21 a[j]:=a[j]+f[b[j]]; 22 for j:=m downto 1 do write(x(a[j])); 23 writeln; 24 end; 25 end.