中国象棋将帅问题java_中国象棋将帅问题

问题:输出中国象棋将帅所有合法位置,且只能用一个字节存储变量。

分析:此问题的本质是搜索、剪枝,只用一个字节存储变量,意义是要进行位运算,或者用C语言中结构体变量中设定的可以使用结构体变量的低4位或者高四位。

互斥的条件是:不能再同一列即可。

第一步:将问题形式化,给这9个位置编号,这是重要的,类似于表征问题的解空间。

第二步:用位或者结构体变量,或者直接根据数字特征来剪枝解空间。位运算中往往要用到逻辑运算来改变各个位的值。

所以产生下面三种解法:

#include "stdafx.h"

#include

//宏定义

#define HALF_BITS_LENGTH4//记忆存储单元的一半

#define FULLMASK255//全部bit的掩码

#define LMASK(FULLMASK<

#define RMASK(FULLMASK>>HALF_BITS_LENGTH)//右bits的掩码

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

#define LSET(b,n)(b=((RMASK&b)|((n)<

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

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

#define GRIDW3//将帅移动范围的行宽度

//解法一

void Solve1()

{

unsigned char b;

for(LSET(b,1);LGET(b)<=GRIDW*GRIDW;LSET(b,(LGET(b)+1)))

for(RSET(b,1);RGET(b)<=GRIDW*GRIDW;RSET(b,(RGET(b)+1)))

if(LGET(b)%GRIDW!=RGET(b)%GRIDW)

printf("A=%d, B=%d\n",LGET(b),RGET(b));

}

//解法二

void Solve2()

{

unsigned int i=81;//9*9=81种组合,搜索、剪枝

while(i--)

{

if(i/9%3==i%9%3)

continue;

printf("A=%d, B=%d\n",i/9+1,i%9+1);

}

}

//解法三

struct

{

unsigned char a:4;//a使用结构体变量i的低4位

unsigned char b:4;//b使用结构体变量i的高4位

}i;

void Solve3()

{

for(i.a=1;i.a<=9;i.a++)

for(i.b=1;i.b<=9;i.b++)

if(i.a%3!=i.b%3)

printf("A=%d, B=%d\n",i.a,i.b);

}

int _tmain(int argc, _TCHAR* argv[])

{

printf("------------解法一----------:\n");

Solve1();

printf("------------解法二----------:\n");

Solve2();

printf("------------解法三----------:\n");

Solve3();

return 0;

}

遇到的问题是:

复杂宏定义的括号匹配问题,根据所有问题的解组合,一共有81中解,然后根据不在同一列的数字特征进行剪枝,是一个可取的方法,不过比较难以理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值