• 中国象棋将帅问题


    问题提出:将和帅想个遥远,且不能照面。在象棋残局中,许多高手利用这一规则走出精妙的杀招。假设棋盘上只有将和帅,请写出一个程序,输出将和帅的所有合法位置。要求代码只能使用一个字节存储变量。(为方便A表示将B表示帅)

    分析和解法:我们想到的应该使用遍历解决即:遍历A的位置

                                                                                遍历B的位置

                                      判断A、B是否合法

                                         如果满足则输出

    1、 存储A、B的位置信息,我们可以建立一个坐标系统, 如下图按从左到右从上到下标上1 2 3 ……  9。这样只需用模余运算就能得到当前的列号,从而判断A、B位置是否合法  

       
       

    2、 寻求单字节变量,我们可以用byte类型,一个byte类型变量8字节, 2^8 = 256 ,足以用来表示A、B位置信息。

    3、如何使用bit级运算将数据从这一byte变量的左边和右边分别存入和读出?

        ①、将byte b(10100101) 的右边4bit(0101)设为n(0011)

           首先清除b右边的bits,同时保持左边的bits

            1111 0000 & 1010 0101 == 1010 0000(b)

           然后将上一步得到的结果与n做或运算

              1010 0000 | 0000 0011  ==  1010 0011

        ②、 将byte b(10100101) 的左边4bit(1010)设为n(0011)

            首先清除b左边的bits,同时保持右边的bits

            0000 1111 & 1010 0101 == 0000 0101(b)

            把n移动到byte数据的左边

              n << 4 == 0011 0000

            然后再或运算 0000 0101 | 0011 0000 == 0011 0101

        三、 得到byte数据的右边4bits 或 左边4bits(eg. 1010 0101 中的1010 和 0101):

          清除b左边的bits,同时保持右边的bits

          0000 1111 & 1010 0101(b) = =0000 0101

          清除b右边的bits,同时保持左边bits

          1111 0000 &  1010 0101 (b) == 1010 0101

          将结果右移4bits

           1010 0000 >> 4 == 0000 1010

    3 、 如何在不声明其他变量约束的前提下创建一个for循环。可以重复利用1byte的存储单元,把它作为循环计数器并用前面提到的存储和读出技术进行操作。

    代码:

    #include<stdio.h>

    #define HALF_BITS_LENGTH 4
    // 存储记忆单元长度的一半, 4bit

    #define FULLMASK 255
    //这个宏表示一个全部bit的mask,它是 1111 1111

    #define LMASK (FULLMASK << HALF_BITS_LENGTH)
    // 这个宏表示左bit, 它是1111 0000

    #define RMASK (FULLMASK >> HALF_BITS_LENGTH)
    // 这个宏表示右bit,它是0000 1111

    #define RSET(b,n) (b = ( (LMASK & b) | n ) )
    //将b的右边设置成n

    #define LSET(b,n) (b = ( (RMASK & b) | ( n << HALF_BITS_LENGTH )) )
    //将b的左边设置成n

    #define RGET(b) (RMASK & b)
    //得到b右边的值

    #define LGET(b) ((LMASK & b)>>HALF_BITS_LENGTH)
    //得到b左边的值

    #define GRIDW 3
    // 将和帅的移动范围

    int mian()
    {
      unsigned char b;
      for( LSET(b,1); LGET(b)<= GRIDW * GRIDW; LSET( b,( LSET(b)+1 )) )
        for( RSET(b,1); RGET(b) <= GRIDW*GRIDW; RSET( b,(RSET(b)+1) ) )
          if(LGET(b)%GRIDW != RGET(b)%GRIDW )
            printf("A = %d, B = %d\n",LGET(b),RGET(b) );
      return 0;

    }

     

  • 相关阅读:
    epoll示例
    realloc的使用误区
    pyCharm最新激活码(2018激活码)
    python程序打包成.exe
    VS2017下载安装
    C# Cache缓存读取设置
    WPF中展示HTML
    Aspose Word模板使用总结
    js alert(“”)弹框 自定义样式
    利用反射将Model转化为sql
  • 原文地址:https://www.cnblogs.com/ATMvip/p/3009984.html
Copyright © 2020-2023  润新知