2019 CSP-S2 Day1T1题解

原题链接(Luogu)

// 就不打freopen了

格雷码(Code)
输入文件名:code.in
输出文件名:code.out
共 20 个测试点,每个测试点 5 分
每个测试点限时 1 秒,运行内存上限 256MB

题目描述

通常,人们习惯将所有 (n) 位二进制串按照字典序排列,例如所有 (2) 位二进制串按字典序从小到大排列为:(00)(01)(10)(11)
格雷码(Gray Code)是一种特殊的 (n) 位二进制串排列法,它要求相邻的两个二进制串间恰好有一位不同,特别地,第一个串与最后一个串也算作相邻。
所有 (2) 位二进制串按照格雷码排列的一个例子为:(00)(01)(11)(10)

(n) 位格雷码不止一种,下面给出其中一种格雷码的生成算法:
(1) 位格雷码由两个一位二进制串组成,顺序为:(00)(11)
(n+1) 位格雷码的前 (2^n) 个二进制串,可以由依此算法生成的 (n) 位格雷码(总共 (2^n)(n) 位二进制串)按顺序排列,再在每个串前加一个前缀 (0) 构成。
(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) 位格雷码为 (0)(1)

前两个格雷码为 0 (0)0 (1)。后两个格雷码为 1 (1)1 (0)。合并得到 (00)(01)(11)(10),编号依次为 (0) ~ (3)

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

已知 (2) 位格雷码为:(00)(01)(11)(10)

前四个格雷码为:0 (00)0 (01)0 (11)0 (10)
后四个格雷码为:1 (10)1 (11)1 (101)1 (00)。合并得到:(000)(001)(011)(010)(110)(111)(101)(100),编号依次为 (0) ~ (7)

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

输入格式

从文件 (code.in) 中读入数据。
仅一行两个整数 (n,k) ,意义见题目描述。

输出格式

输出到文件 (code.out) 中。
仅一行一个 (n) 位二进制串表示答案。

样例

样例 1 输入

1
2 3

样例 1 输出

1
10

样例 1 解释

(2) 位格雷码为:(00)(01)(11)(10),编号从 (0) ~ (3),因此 (3) 号串是 (10)

样例 2 输入

1
3 5

样例 2 输出

1
111

样例 2 解释

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

数据范围

对于 (50\%) 的数据:(n ≤ 10)

对于 (80\%) 的数据:(k ≤ 5 imes 10^6)

对于 (95\%) 的数据:(k ≤ 2 ^ {63}-1)

对于 (100\%) 的数据:(1 le n le 64)(0 le k lt 2^n)

95' 代码


#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef unsigned long long llu;
int main(){
	freopen("code.in","r",stdin);freopen("code.out","w",stdout);
	int n ;
	llu k ;
	scanf("%d%llu",&n,&k);
	k += 1 ;
	llu now = pow(2,n);
	bool num = 0 ; 
//	printf("%llu %llu
",now,k); 
	if(k > now / 2)printf("1");
	else printf("0");
	if(n > 1){ 
		
		for(int i = 2 ; i <= n ; i ++){
//			printf("

---%d %llu %llu---

",i,now,k);
			k %= now ;
			if(now > 4){
				if(k <= (now / 4) || k > ((3 * now) / 4))printf("0");
				else printf("1");
			}
			else {
				if(k <= 1 || k >= 4)printf("0");
				else printf("1");
			}	 
			now /= 2 ;
		}
	}
	
//	printf("%llu %llu %d",now, k , n );
	return 0 ;
} 
原文地址:https://www.cnblogs.com/Shinomiya/p/13888738.html