木有寸557

 

中国象棋将帅问题

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

}

 

 

 

posted on 2013-04-09 13:57  小猪_你快跑  阅读(270)  评论(0编辑  收藏  举报

导航