在中国象棋里将和帅是不能碰面的,如下图所示,当将位于d10时,帅就不能在d1、d2、d3。请写一个程序,输出将、帅所有的合法位置。要求在代码中仅用一个变量。

如果只是输出将、帅的合法位置,那这题就比较容易了,只要二重循环判断一下就行,但后面一个条件就将题目的难度上升了好多。

因为是判断两个对象A、B的位置符不符合要求,而且每个对象一共就只有9个位置可选,可以比较快地想到程序的大体框架:

因为每个对象只有9个位置,所以循环次数一共也就81次。

所以,我们需要先给A、B定好坐标系统,下面使用以行优先的顺序使用1-9来表示坐标:

因为只使用1个变量,而我们要存储的是两个对象的坐标(同时坐标也是循环的计数器),所以我们可以通过分割变量的位达到数据存储的目的。因为char型是8位,可以表示256个数,所以,我们可以用char型变量来表示A、B两个对象的坐标;具体就是使用左边4位表示A坐标,右边4位表示B坐标。

左右两边都要能通过位运算从1遍历到9。下面是编程之美上的代码:

位运算是通过宏实现的,LSET、LGET分别是设置和获取左边四位的值;RSET、RGET分别是设置和获取右边四位的值。

判断A、B坐标是否符合要求是通过求两个位置除以3的余数来判断的。

刚开始看到这题的解法的时候惊呆了,真没有想到那群人竟然能把位运算运用到这地步。不过,就在我为这种方法赞叹的时候,编程之美上又有一位仁兄提出下面的解法:

第一种解法是利用位运算,第二种解法利用的是数学运算,如代码中的那行注释:

以81-73为例,i/9一直是8,i%9是08-1 ,通过这种普通(巧妙)的数学运算就到达了遍历的目的。

问题: 检测数组里是否有两个数之和等于某个数 解决方法一:先将数组排序,然后从两头开始遍历 数组排序后,从左端开始取最小值,从右端取最大值, 判断两者之和与目标的大小: 等于时,输出两个数; 大于时,右端移到第2个数,继续判断; 小于时,左端移到第2个数,继续判断。