中国象棋将帅问题
问题描述:
在中国象棋规则中,将和帅规定只能在田字格中移动,且将和帅是不能碰面的,
请求解出所有可能的符合规则的将帅位置。
A:
B:
限制条件:
只能使用一个字节的变量
问题解答:
解法很简单,不在一条直线,%3不相等即可;
如何只用一个字节来表示所有需要用到变量,是关键。
解法一:用位表示变量
8位可以表示2^8=256个值,前4bit表示A,后4bit表示B;
#include
#include
using namespace std;
#define HALF_BITS_LENGTH 4 //存储单元长度的一半,即4位
#define FULLMASK 255 //存储单元全部bit的mask(掩码),11111111,为0Xff;
#define LMASK (FULLMASK#define RMASK (FULLMASK>>HALF_BITS_LENGTH) //右四位。00001111,0x0f
#define RSET(b,n) (b=((LMASK&b)|(n)))
//将b的4位设置为n,首先清空右4位LMASK&b,然后|n;
#define LSET(b,n) (b = ((RMASK &b) | (n) //将b左4位设置为n,首先清空左4位RMASK&b,然后n左移4位,在进行|运算;
#define RGET(b) (RMASK&b) //得到b右四位的值
#define LGET(b) ((LMASK&b)>> HALF_BITS_LENGTH) //得到b左四位的值
#define GRIDW 3 // 九宫格边界长度
int main()
{
unsigned char b;
for(LSET(b,1);LGET(b) {
for(RSET(b,1);RGET(b) {
if(LGET(b)%GRIDW!=RGET(b)%GRIDW)
{
printf("A=%d,B=%dn",LGET(b),RGET(b));
}
}
}
return 0;
}
解法二、
整数i可以由部两分组成,即i=(i/9)*9+i%9 ,其中i
我们注意到,在i从81到0变化的过程中,i%9的变化相当于内层循环(0,1,2..8),
i/9的变话相对于外层循环(0,1…8),一个表示对面的,一个表示自己的
#include
using namespace std;
typedef unsigned char BYTE;
int main()
{
BYTE i=81;//9*9
while(i--)
{
if(i/9%3==i%9%3)//内层循环%3,外层循环%3,相等在一条直线
continue;
cout }
return 0;
}