问题描述:

在中国象棋规则中,将和帅规定只能在田字格中移动,且将和帅是不能碰面的,请求解出所有可能的符合规则的将帅位置。

限制条件:

只能使用一个字节的变量

问题解答:

刚看到问题时,觉得问题本身的逻辑关系很简单,限制条件才是本题的精妙之处,如何只用一个字节来表示所有需要用到变量,我们一步一步的分析;

首先,将题目中所提的场景使用数学方法描述为:

7    8    9

将的移动范围为 Matrix A  =   4    5    6

1    2    3

同理:

7    8    9

帅的移动范围为 Matrix B  =   4    5    6

1    2    3

如果没有限制条件,则本题解法很容易想到:

S1:a=将当前位置号;

S2:b=帅当前位置号;

S3: IF abs(a-b)%3 != 0 THEN 符合  ELSE 不符合;

但是,有了限制条件后,需要将a,b变为一个单字节的变量,这最先想到的就是利用除法,因为四则运算中只有除法可以将一个数变为两个, N/n = q...r N被除数,n除数,q商,r余数,这样我们就找到了使a,b变为一个数的方法。

根据A,B两个矩阵易知:1、总共存在81种可能的情况;2、重新将矩阵转为以0为开始,易于计算

设Num为某种情况的标号,则Num的范围为[0,80]共81种,a=Num/9,b=Num%9

则可以得到a,b,并利用S3就可以得到所有符合规则的解;

重新整理算法为:

for Num=0:80

a=Num/9;

b=Num%9;

if(abs(a-b))!=0

printf("a = %d, b = %d"a+1,b+1);

这样就完成了,但仔细想想,肯定有有效地方法,因为被限制为单字节,所以很自然想到用位来扩展,所以给出经过位处理的代码:

struct {

unsigned char a:4;

unsigned char b:4;

} i;

int main()

{

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);

return 0;

}

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐