P5657 格雷码【民间数据】

题解

其实这题水啊

打表找规律

【1】0   1

【2】00   01  11  10

【3】000   001   011   010   110   111   101   100

【4】0000   0001   0011   0010   0110   0111   0101   0100

1100   1101   1111    1110   1010   1011   1001   1000

然后我们发现这题其实可以二分

1.0 真的以为这题很水

n位的二进制格雷码一共有2n

目的输出编号为k的二进制格雷码

二分查找,查找区间为[ 0 , 2n-1 ]

然后我们像剥洋葱一样,从外到内一层一层输出,一共输出n层

(1)如果k在区间左边,那么显然当前最外层的数字应该是0,否则就是1

(2)然后我们继续往下找,继续缩小查找区间

大体框架是酱紫

while(l!=r)
{
mid=(l+r)>>;
if(k<=mid) printf("");
else printf("");
}

2.0  不好好分析题意

其实仔细分析过打表的人会发现,这么做,问题hin大,样例1可以水过,样例2,3就完蛋

问题出在这一句:

我们分析,如果上一层你是从上层区间右边转移到下一层的,那么读题目:

显然是要标记一下,也就是本来应该输出1,实际上你是由上一层逆序得到,所以相应的应该改为输出0

也就是二分思路改为:

(1)若k在当前查找区间左边,如果它是由上一个查找区间的左区间转移过来,输出0,如果它是由上一个查找区间的右区间转移过来,输出1

(2)若k在当前查找区间右边,如果它是由上一个查找区间的左区间转移过来,输出1,如果它是由上一个查找区间的右区间转移过来,输出0

注意:

这里我们用flag标记是否从上一层的右区间转移来

大体框架:

while(l!=r)
{
mid=(l+r)>>;
if(k<=mid){
if(flag) printf("");
else printf("");
r=mid,flag=;
}
else{
if(flag) printf("");
else printf("");
l=mid+,flag=;
}
}

恭喜你!

我还是第一次看见这样的结果。。。

3.0  暂时性迷惑行为

所以问题出在哪里???

和神仙讨论之后呢,发现问题很大啊QAQ

1.要用 unsigned long long ,你看这样就很危险会出现负数(数字超范围)   

2.为什么要用while呢(TLE警告)

反正每次都是缩小一半的搜索区间,记录下来这几个数字不就好了

4.0终极版

然后第二天重新整理了下思路,重构代码:

1.由于每次二分查找实际用到的只是区间中点mid,所以我们只把mid移动就好了

注意格雷码编号0~2n-1,所以mid做了减1处理

2.用for循环实现

3.p定位区间长度,也就是每次搜下一个区间时,mid的移动量

4.flag表示是否由上一个区间的右半边转移来

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<queue> using namespace std; typedef unsigned long long ll; inline ll read()
{
ll ans=;
char last=' ',ch=getchar();
while(ch<''||ch>'') last=ch,ch=getchar();
while(ch>=''&&ch<='') ans=ans*+ch-'',ch=getchar();
if(last=='-') ans=-ans;
return ans;
} ll n,k;
ll num[]={,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,};
bool flag=; int main()
{
n=read();k=read();
ll mid=num[n-]-,p=n-;
for(int i=;i<=n;i++){
p--;
if(k<=mid){
if(flag) printf("");
else printf("");
flag=;
mid-=num[p];
}else{
if(flag) printf("");
else printf("");
flag=;
mid+=num[p];
}
} return ;
}

P5657 格雷码【民间数据】的更多相关文章

  1. P5657 格雷码

    思路 考场上的递归思路 每次向下递归的时候判断是左半边还是右半边即可 注意向右半边递归之后下一层序列要反转过来即可 代码 #include <cstdio> #include <al ...

  2. P2328 [SCOI2005]超级格雷码

    P2328 [SCOI2005]超级格雷码 暴力出奇迹喵! 这是一道模拟题 你会发现和 P5657 格雷码[民间数据]有异曲同工之妙,这道题直接按照上边链接题目的操作步骤 暴力模拟 就可以啊 我们观察 ...

  3. 【解题报告】CSP2019-S D1T1 格雷码

    题目链接:https://www.luogu.org/problem/P5657 话说这道题怎么是道橙题啊. 基本思路 因为n位格雷码的前2n-1位就是n-1位格雷码前面加了一位‘0’,所以可以把它们 ...

  4. BZOJ1081[SCOI2005]超级格雷码

    Description 著名的格雷码是指2n个不同n位二进制数(即0~2n-1,不足n位在前补零)的一个排列,这个排列满足相邻的两个二进制数的n位数字中最多只有一个数字不同(例如003和001就有一个 ...

  5. 格雷码原理与Verilog实现

    格雷码原理 格雷码是一个叫弗兰克*格雷的人在1953年发明的,最初用于通信.格雷码是一种循环二进制码或者叫作反射二进制码.格雷码的特点是从一个数变为相邻的一个数时,只有一个数据位发生跳变,由于这种特点 ...

  6. 原码、反码、补码、BCD码、格雷码

    二进制的最高位表示这个二进制的正负符号(0为正,1为负),其余各位数表示其数值本身称为原码. 正数的反码等于原码,负数的反码是在原码的基础上,符号位不变,其余各位取反. 正数的补码等于原码,负数的补码 ...

  7. 洛谷 P3955 图书管理员【民间数据】

    P3955 图书管理员[民间数据] 题目背景 数据已再次修正 (既然你们不要前导0我就去掉了) 题目描述 图书馆中每本书都有一个图书编码,可以用于快速检索图书,这个图书编码是一个 正整数. 每位借书的 ...

  8. 2019CSP day1t1 格雷码

    题目描述 通常,人们习惯将所有 \(n\) 位二进制串按照字典序排列,例如所有 \(2\) 位二进制串按字典序从小到大排列为:\(00,01,11,10\). 格雷码(\(Gray Code\))是一 ...

  9. 在verilog中使用格雷码

    格雷码的一些知识: https://baike.baidu.com/item/%E6%A0%BC%E9%9B%B7%E7%A0%81/6510858?fr=aladdin 绿色框起来的是0--15的格 ...

随机推荐

  1. C++ 语句函数再探

    1. 表达式只计算,抛弃计算结果: 2. 空语句什么也不做: 3.switch case语句漏写break,将会从匹配到的情况开始执行,直到语句结束 int main() { ; i + ; //表达 ...

  2. OpenCV 图象腐蚀形态学操作 全家桶

    图象腐蚀与形态学操作 opencv 1. 通过调用库函数实现图像的腐蚀.膨胀: 2. 通过设置结构元素.元素大小.形态学操作类型实现对图象的形态学操作. 源码(VS2017+OpenCV 4.0) # ...

  3. 当前form窗体随系统屏幕变化

    private void 新建_Load(object sender, EventArgs e) { int DeskWidth = Screen.PrimaryScreen.WorkingArea. ...

  4. 深度解析Droupout与Batch Normalization

    Droupout与Batch Normalization都是深度学习常用且基础的训练技巧了.本文将从理论和实践两个角度分布其特点和细节. Droupout 2012年,Hinton在其论文中提出Dro ...

  5. java-利用BitSet查找素数

    高效存储为序列可以使用位积,由于位集将位包装在字节里,所以位集要比使用Boolean对象的ArrayList更高效. 自己的代码,素数是false public class Sieve { @Test ...

  6. v-model原理解析

    vue中v-model可以实现数据的双向绑定,但是为什么这个指令就可以实现数据的双向绑定呢? 其实v-model是vue的一个语法糖.即利用v-model绑定数据后,既绑定了数据,又添加了一个inpu ...

  7. Java8-LongAccumulator

    import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util ...

  8. 怎么学好js

    Js给人那种感觉的原因多半是因为它如下的特点: A:本身知识很抽象.晦涩难懂,如:闭包.内置对象.DOM. B:本身内容很多,如函数库.对象库就一大堆. C:混合多种编程思想.它里面不但牵涉面向过程编 ...

  9. 边学边体验django--模型

    步骤: 1.选定数据库,然后修改 settings.py 中的 DATABASES配置 实验过了sqlite3. 应该是这个样子的: 2. 创建app, 建立数据表模型. python manage. ...

  10. C#读取App.config/Web.config

    读取需要添加 System.Configuration 引用, 两种方式添加: 1:.NETFramework程序可以在引用右击添加引用,然后添加System.Configuration 2:引入Nu ...