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;
    }
    
  • 相关阅读:
    ACM 2的N次方
    文件默认打开方式 转
    java 的 一点记录
    zhuan 漫谈C语言及如何学习C语言
    eclipse
    code::blocks
    心态决定命运_no excuses, suck it up, obey your teacher
    uml_2_application and viso application
    paint conflict with lingoes
    stm learning record
  • 原文地址:https://www.cnblogs.com/AlexKing007/p/12338460.html
Copyright © 2011-2022 走看看