2019 csp-s 解析及代码
T1 格雷码
题目大意
格雷码是一种特殊的 n n n 位二进制串表示方法,它要求相邻的两个二进制串之间恰好有一位不同,特别地,第一个串和最后一个串也算相邻。
现在给定一个 n n n 和一个 k k k ,要求你输出 n n n 位格雷码中的第 k k k 个。注意,所有格雷码的编号从 0 0 0 开始。
输入格式
一行两个正整数 n n n 和 k k k ,含义如题中描述。
数据范围
对于所有测试数据, 1 ≤ n ≤ 64 1 \le n \le 64 1≤n≤64, 0 ≤ k ≤ 2 n 0 \le k \le 2^{n} 0≤k≤2n。
思路
我们先将 3 3 3 位和 4 4 4 为格雷码依次列出来,如下图:
3 3 3 位:
码 | 序号
000| 0
001| 1
011| 2
010| 3
110| 4
111| 5
101| 6
100| 7
4 4 4 位:
码 | 序号
0000 | 0
0001 | 1
0011 | 2
0010 | 3
0110 | 4
0111 | 5
0101 | 6
0100 | 7
1000 | 8
1001 | 9
1011 | 10
1010 | 11
1110 | 12
1111 | 13
1101 | 14
1100 | 15
通过观察可以发现,对于 n n n 位的格雷码,除了第 n n n 位,其他位上都满足这样一个性质:
在第 i i i 位上的区间 [ 2 i − 1 , 2 n − 2 i − 1 − 1 ] [2^{i - 1}, 2^{n} - 2^{i - 1} - 1] [2i−1,2n−2i−1−1] 上,数字 0 0 0 和 1 1 1 以连续的 2 i 2^{i} 2i 个重复出现。 例如 4 4 4 位格雷码的第 2 2 2 位上:
0 | 0
0 | 1
1 | 2 2 − 1 = 2 2^{2 - 1} = 2 22−1=2
1 | 3
1 | 4
1 | 5
0 | 6
0 | 7
0 | 8
0 | 9
1 | 10
1 | 11
1 | 12
1 | 2 4 − 2 2 − 1 − 1 = 13 2^{4} - 2^{2 - 1} - 1 = 13 24−22−1−1=13
0 | 14
0 | 15
同时我们可以发现,在除了上述区间以外的区域,所有位数上都是 0 0 0 。(包括第 n n n 位)
而对于第 n n n 位,显然区间 [ 0 , 2 n − 1 − 1 ] [0, 2^{n - 1} - 1] [0,2n−1−1] 上都是 0 0 0 ,区间 [ 2 n − 1 , 2 n − 1 ] [2^{n - 1}, 2^{n} - 1] [2n−1,2n−1] 上都是 1 1