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