# NOIP2019_Day1T1_格雷码

题意:


n 位格雷码指有 2n 个长度为 n 的01字符串的排列,且相邻两个字符串只有一位不同,例如:

1位格雷码:0,1

2位格雷码:00,01,11,10

3位格雷码:000,001,011,010,110,111,101,100

显然,i+1 位格雷码的个数是 i 位格雷码个数的2倍

现有一种生成格雷码的算法:

规定一位格雷码为 1,0

n 位格雷码的前 2n1 个可由 n1 位格雷码顺序排列,并在每个串的前面补上一个0得到

n 位格雷码的后 2n1 个可由 n1 位格雷码逆序排列,并在每个串的前面补上一个1得到

那么问题来了,给定 n,kn <= 64, k <= 264 ,求 n 位格雷码的第 k 个是多少?

解:


找规律,看看 k 和答案有什么关系

答案的 0位 1位 2位 ... k = 0000 0 0 0 0001 1 0 0 0010 1 1 0 0011 0 1 0 0100 0 1 1 0101 1 1 1 0110 1 0 1 0111 0 0 1 1000 0 0 1 1001 1 0 1 1010 1 1 1 1011 0 1 1 1100 0 1 0 1101 1 1 0 1110 1 0 0 1111 0 0 0

emm...貌似有点什么规律,但又说不清...

但是当你把 k 的0,1位与答案的0位比较————你会惊人的发现答案的0位恰巧等于 k 的0,1位异或结果!

同理,把 k 的1, 2位与答案的1位比较发现答案的1位恰等于 k 的1,2位异或结果

那么我们有了一个大胆的想法:把 k 整体向右移一位再与 k 本身异或,得出的就是结果!

至于是 n 位嘛,顺次输出结果的从 n1 到0位就好了

代码:


所以就有了这令人惊叹的代码

*k一定要开ull,因为普通ll最大只能记录 2631 ,但是k要求最大到 264

#include <bits/stdc++.h> using namespace std; int n; unsigned long long k; int main(){ cin >> n >> k; k ^= k >> 1; while(~--n) cout << (k >> n & 1); }

__EOF__

本文作者熹圜
本文链接https://www.cnblogs.com/Xiwon/p/13402228.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   熹圜  阅读(210)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示