版权声明:本文为博主原创文章,转载请注明出处-- https://blog.csdn.net/qq_38790716/article/details/90272026
如下图
将 被限制于{ }组成的正方形中,帅 被限制于{ }组成的正方形中,要求将和帅不能照面,给出将和帅的所有合法位置;如果没有特别的要求,那么应该用一个双重循环即可搞定,但题目中给出限制:只能使用一个字节存储变量
解法一 (位运算)
一个字节也即 ,而我们需要保存将和帅两个点的位置信息,对于将/帅 大小存储足够描述其 种位置,所以可以将 分为左右两边,左边 存储将的位置,右边 存储帅的位置,通过位运算不断更新左值与右值的大小,达到双重循环遍历的效果
#include <iostream>
#include <time.h>
using namespace std;
#define HALF_BITS_LENGTH 4 //4bits
#define FULLMASK 255 //一个完整bits,为11111111
#define LMASK (FULLMASK << HALF_BITS_LENGTH) //表示左bits,为11110000
#define RMASK (FULLMASK >> HALF_BITS_LENGTH) //表示右bits,为00001111
#define RSET(b, n) (b = ((LMASK & b) | (n))) //将b的右边设置为n
#define LSET(b, n) (b = ((RMASK & b) | ((n) << HALF_BITS_LENGTH))) //将b的左边设置为n
#define RGET(b) (RMASK & b) //获得b右边的值
#define LGET(b) ((LMASK & b) >> HALF_BITS_LENGTH) //获得b左边的值
#define GRIDW 3 //表示将帅移动范围的行宽度
int main() {
unsigned char b;
clock_t start, finish;
start = clock();
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) {
cout << "A = " << LGET(b) << ",B = " << RGET(b) << endl;
}
}
}
finish = clock();
cout << endl << "runTime: " << (double)(finish - start) / CLOCKS_PER_SEC << "s" << endl;
return 0;
}
测试结果:
解法二 (/、%)
利用 、%进行遍历, ~ 可以得到 ,而利用%则可以得到 ~ ,这样就达到了遍历的作用
#include <iostream>
#include <time.h>
using namespace std;
int main() {
unsigned char i = 81;
clock_t start, finish;
start = clock();
while (i--) {
if (i / 9 % 3 == i % 9 % 3)
continue;
cout << "A = " << i / 9 + 1 << ",B = " << i % 9 + 1 << endl;
}
finish = clock();
cout << "runTime: " << (double)(finish - start) / CLOCKS_PER_SEC << "s" << endl;
return 0;
}
测试结果:
解法三 (结构体、位域)
利用位域性质,限定变量存储地址,例:unsigned char a : 4,表示只用其中的低4位,然后双重循环遍历
#include <iostream>
#include <time.h>
using namespace std;
struct {
unsigned char a : 4;
unsigned char b : 4;
} i;
int main() {
clock_t start, finish;
start = clock();
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)
cout << "A = " << (int)i.a << ",B = " << (int)i.b << endl;
}
}
finish = clock();
cout << "runTime: " << (double)(finish - start) / CLOCKS_PER_SEC << "s" << endl;
return 0;
}
测试结果: