写一个虽然没什么难度,但看书看到了的题。
题目如下:

可以看出,此题不难,最简单的方法就是遍历了,当我们首先遍历“将”的位置,再遍历“帅”的位置,然后判定当前位置是否满足题意,即有效,即可!但是关键点在于最后一句话,要求代码中只能使用一个字节存储变量。我们都知道,一个字节也就是一个bit,8位。那么从这里出发,可以看出考题人用意在于考察位运算的掌握程度。
所以,我主要说一下位运算:
| 含义 | Pascal语言 | C语言 | C#语言 | Java |
|---|---|---|---|---|
| 按位与 | a and b | a & b | a & b | a & b |
| 按位或 | a or b | a | b | a | b | a | b |
| 按位异或 | a xor b | a ^ b | a ^ b | a ^ b |
| 按位取反 | not a | ~a | ~a | ~a |
| 左移 | a shl b | a << b | a << b | a << b |
| 带符号右移 | a shr b | a >> b | a >> b | a >> b |
| 无符号右移 | a>>> b |
主要常用的有三种(其中“非”没讲,即按位取反):
与
00101
11100
(&;或者and)
—————
00100
或
00101
11100
(|或者or)
—————
11101
异或
00101
11100
(^或者xor)
—————-
11001
接下来讲一下题解:
我们按照一个bit数来看的话,四位即二进制的1111可以表示到十进制数15,所以我们可以按照前四位与后四位的数来表示(unsigned char),然后通过对其位操作,改变其数值大小,最后检查位置的有效性,输出即可;
能表示的位置,我们假设成如下图

代码如下:
#include <iostream>
using namespace std;
//表示一个bit的一般长度(一个bit 8位)
#define HALF_BIT_LENGTH 4
//表示一个bit的全码即二进制表示为 11111111
#define FULLMASK 255
//表示一个bit的前四位的全码,即 11110000
#define LMASK (FULLMASK << HALF_BIT_LENGTH)
//表示一个bit的后四位的全码, 即 00001111
#define RMASK (FULLMASK >> HALF_BIT_LENGTH)
//设置前四位为n
#define LSET(num, n) (num = (num & RMASK) | (n << HALF_BIT_LENGTH))
//设置后四位为n
#define RSET(num, n) (num = (num & LMASK) | n)
//获取前四位的值
#define LGET(num) ((num & LMASK) >> HALF_BIT_LENGTH)
//获取后四位的值
#define RGET(num) (num & RMASK)
//定义棋子的移动范围,本题中将帅移动方阵为 3 * 3
#define MROW 3
int main(void)
{
//定义变量,表示当前将帅的位置
unsigned char temp;
//初始化左节点循环
for (LSET(temp, 1); LGET(temp) <= MROW * MROW; LSET(temp, (LGET(temp) + 1)))
{
//初始化右节点循环
for (RSET(temp, 1); RGET(temp) <= MROW * MROW; RSET(temp, (RGET(temp) + 1)))
{
//判断当前位置是否有效
if ((LGET(temp) % MROW) != (RGET(temp) % MROW))
{
//位置有效,则输出
cout << "If A stay at " << LGET(temp) << ", B effective position is " << RGET(temp) << endl;
}
}
}
return 0;
}
结果输出如下:

423

被折叠的 条评论
为什么被折叠?



