zoukankan      html  css  js  c++  java
  • 2018第九届蓝桥杯C/C++ B国赛 —— 第三题:格雷码

    格雷码

    格雷码是以n位的二进制来表示数。
    与普通的二进制表示不同的是,它要求相邻两个数字只能有1个数位不同。
    首尾两个数字也要求只有1位之差。

    有很多算法来生成格雷码。以下是较常见的一种:
    从编码全0开始生成。
    当产生第奇数个数时,只把当前数字最末位改变(0变1,1变0)
    当产生第偶数个数时,先找到最右边的一个1,把它左边的数字改变。
    用这个规则产生的4位格雷码序列如下:
    0000
    0001
    0011
    0010
    0110
    0111
    0101
    0100
    1100
    1101
    1111
    1110
    1010
    1011
    1001
    1000

    以下是实现代码,仔细分析其中逻辑,并填写划线部分缺少的代码。

    #include <stdio.h>
    void show(int a,int n)
    {
    	int i;
    	int msk = 1;
    	for(i=0; i<n-1; i++) msk = msk << 1;
    	for(i=0; i<n; i++){
    		printf((a & msk)? "1" : "0");
    		msk = msk >> 1;
    	}
    	printf("\n");
    } 
    
    
    void f(int n)
    {
    	int i;
    	int num = 1;
    	for(i=0; i<n; i++) num = num<<1;
    	
    	int a = 0;
    	for(i=0; i<num; i++){
    		show(a,n);
    		
    		if(i%2==0){
    			a = a ^ 1;
    		}
    		else{
    			a = _________________________ ; //填空
    		}
    	}
    }
    
    
    int main()
    {
    	f(4);
    	return 0;
    }
    

    代码

    #include <stdio.h>
    void show(int a,int n)
    {
        int i;
        int msk = 1;
        for(i=0; i<n-1; i++) msk = msk << 1;
        for(i=0; i<n; i++){
            printf((a & msk)? "1" : "0");
            msk = msk >> 1;
        }
        printf("\n");
    }
    
    
    void f(int n)
    {
        int i;
        int num = 1;
        for(i=0; i<n; i++) num = num<<1;
    
        int a = 0;
        for(i=0; i<num; i++){
            show(a,n);
    
            if(i%2==0){//当产生第奇数个数时,先找到最右边的一个1,把它左边的数字改变。
                a = a ^ 1;      //1=0001
                /*
                 * 异或运算,不同则为1,相同则为0,
                 * 如果a的最后一位数是1,则变为0,
                 * 左边三位数如果是1,与0不同,还是1,如果是0,与0相同,还是0;
                 * 如果a的最后一位数是0,则变为1,
                 * 左边三位数如果是1,与0不同,还是1,如果是0,与0相同,还是0;
                 * 把一个数字与1异或将翻转数字的最后一位。
                 */
            }
            else{//由上可知,else处理的是偶数个数的情况,当产生第偶数个数时,先找到最右边的一个1,把它左边的数字改变;
                a=a^((a&(-a))<<1);
                /*
                 * 将a和-a相与,得到的结果是a的最右边的1加上末尾的0的数的大小,
                 * 再将结果左移一位就是要翻转的位,
                 * 最后与a异或一下就可翻转。
                 */
    //            a = _________________________ ; //填空
            }
        }
    }
    
    
    int main()
    {
        f(4);
        return 0;
    }
    
  • 相关阅读:
    PLSQL WEBSERVICES 发布
    WebService开发指南
    来自10位成功IT人士的23条经验教训
    图片格式区别:png8,png24,jpg,jpeg,gif,webp
    当你在工作中失去动力时该怎么办?
    面向对象的反思
    关于前端面试的一些心得
    有什么好的交友软件吗?求推荐
    区块链开发的11种顶级编程语言
    CSRF的几种防御方法的利弊分析
  • 原文地址:https://www.cnblogs.com/AlexKing007/p/12338460.html
Copyright © 2011-2022 走看看