万卷网 > 题目详情
题型:简答题

格雷码

【题目描述】

通常,人们习惯将所有n位二进制串按照字典序排列,例如所有2位二进制串按 字典序从小到大排列为:00, 01, 10, 11

格雷码(Gray Code)是一种特殊的n位二进制串排列法,它要求相邻的两个二进 制串间恰好有一位不同.特别地,第一个串与最后一个串也算作相邻。

所有2位二进制串按格雷码排列的一个例子为:00, 01, 11, 10。

n位格雷码不止一种,下面给出其中一种格雷码的生成算法:

1.1位格雷码由两个1位二进制串组成,顺序为:0, 1。

2.n + 1位格雷码的前2^n个二进制串,可以由依此算法生成的n位格雷码(总共 2^n个n位二进制串)按顺序排列,再在每个串前加一个前缀0构成。

3.n + 1位格雷码的后2^n个二进制串,可以由依此算法生成的n位格雷码(总共 2^n个n位二进制串)按逆序排列,再在每个串前加一个前缀1构成。

综上,n + 1位格雷码,由n位格雷码的2^n个二进制串按顺序排列再加前缀0,和 按逆序排列再加前缀1构成,共2^n+1个二进制串。另外,对于n位格雷码中的2^n个 二进制串,我们按上述算法得到的排列顺序将它们从0~2^n - 1编号。

按该算法,2位格雷码可以这样推出:

1.己知1位格雷码为0, 1

2.前两个格雷码为00, 01.后两个格雷码为11, 10。合并得到00, 01, 11, 10, 编号依次为0〜3。

同理,3位格雷码可以这样推出:

1.己知2位格雷码为:00, 01, 11 10。

2.前四个格雷码为:000, 001, 011.010。后四个格雷码为:110, 111, 101, 100。合并得到:000, 001. 011, 010, 110, 111. 101, 100,编号依次为 0 ~7。

现在给出n,k请你求出按上述算法生成的n位格雷码中的k号二进制串。

【输入格式】

从文件code.in中读入数据。

仅一行两个整数n,k意义见题目描述。

【输出格式】

输出到文件code.out中。

仅一行一个n位二进制串表示答案。

【样例1输入】

23

【样例1输出】

10

【样例1解释】

2位格雷码为:00, 01, 11. 10,编号从0〜3,因此3号串是10。

【样例2输入】

35

【样例2输出】

111

【样例2解释】

3 位格雷码为:000, 001. 011, 010, 110, 111. 101, 100,编号从 0 〜7,因此 5 号串是111。

【数据范围】

对于50%的数据:n≤ 10

对于80%的数据:k≤5x10^6

对于95%的数据:k≤  2^63 - 1

对于 100% 的数据:1 ≤ n ≤ 64,0 ≤ k≤2^n

更新时间:2022-12-05 17:30:28 |
【知识点】 信息学NOIP提高组

相似题推荐

填空题

如下图所示,A到B是连通的。假设删除一条细的边的代价是1,删除一条粗的边的代价是2,要让A、B不连通,最小代价是_____(2分),最小代价的不同方案数是_______(3分)。(只要有一条删除的边不同,就是不同的方案)

2023-09-02
单选题

中国计算机学会于( )年创办全国青少年计算机程序设计竞赛。(2018年提高组)

A.

1983

B.

1984

C.

1985

D.

1986

2023-09-02
填空题

如右图所示,共有13个格子。对任何一个格子进行一次操作,会使得它自己以及与它上下左右相邻的格子中的数字改变(由1变0,或由0变1)。现在要使得所有的格子中的数字都变为0,至少需要      次操作。

2023-09-02
简答题

(最长路径)给定一个有向无环图,每条边长度为1,求图中的最长路径长度。(第五空2分,其余3分)

输入:第一行是结点数n(不超过100)和边数m,接下来m行,每行两个整数a,b,表示从结点a到结点b有一条有向边。结点标号从0到(n-1)。

输出:最长路径长度。

提示:先进行拓扑排序,然后按照拓扑序计算最长路径。


#include <iostream>

using namespace std;


int n, m, i, j, a, b, head, tail, ans;

int graph[100][100]; // 用邻接矩阵存储图

int degree[100]; // 记录每个结点的入度

int len[100]; // 记录以各结点为终点的最长路径长度

int queue[100]; // 存放拓扑排序结果


int main() {

cin >> n >> m;

for (i = 0; i < n; i++)

for (j = 0; j < n; j++)

graph[i][j] = 0;

for (i = 0; i < n; i++)

degree[i] = 0;

for (i = 0; i < m; i++) {

cin >> a >> b;

graph[a][b] = 1;

                 (1)           ;

}

tail = 0;

for (i = 0; i < n; i++)

if (      (2)      ) {

queue[tail] = i;

tail++;

}

head = 0;

while (tail < n - 1) {

for (i = 0; i < n; i++)

if (graph[queue[head] ][i] == 1) {

                               (3)        ;

if (degree[i] == 0) {

queue[tail] = i;

tail++;

}

}

                  (4)        ;

}

ans = 0;

for (i = 0; i < n; i++) {

a = queue[i];

len[a] = 1;

for (j = 0; j < n; j++)

if (graph[j][a] == 1 && len[j] + 1 > len[a])

len[a] = len[j] + 1;

if (      (5)      )

ans = len[a];

}

cout << ans << endl;

return 0;

}

2023-09-02
单选题

设A和B是两个长为n的有序数组,现在需要将A和B合并成一个排好序的数组,请问任何以元素比较作为基本运算的归并算法最坏情况下至少要做( )次比较。

A.

n2

B.

n logn

C.

2n

D.

2n-1

2023-09-02
公众号
客服 反馈
顶部