编程之美-中国象棋将帅问题
来源:互联网 发布:淘宝大悦运动怎么样 编辑:程序博客网 时间:2024/04/30 19:27
在中国象棋规则中,将和帅规定只能在田字格中移动,且将和帅是不能碰面的,请求解出所有可能的符合规则的将帅位置。
限制条件:
只能使用一个字节的变量
问题解答:
1 2 3
将的移动范围: 4 5 6
7 8 9
1 2 3
帅的移动范围: 4 5 6
7 8 9
如果没有限制条件(使用一个字节的变量),则本题容易解决:
S1:a=将当前位置号
S2:b=帅当前位置号
S3:if a%3 != b%3 符合 else 不符合
注:a%3和b%3分别得到a、b所在的列
#include<iostream>
using namespace std;
//不对存储空间进行限制
int main(){
for (char a=9; a>0; a--)
for(char b=9; b>0; b--)
if(a%3 != b%3)
printf("a = %d, b = %d\n",a, b);
return 0;
}
方法一:
题目限制只能使用一个字节,即8位,我们可以将8位进行拆分,前4位存放a的位置1-9,后4位存放b的位置1-9.(4位能表示的范围为0-15,所以肯定能存放9以内的数字),所以要解决如何从8位字节中提取前4位和后4位。
#define HALF_BITS_LENGTH 4
// 这个值是记忆存储单元长度的一半,在这道题里是4bit
#define FULLMASK 255
// 这个数字表示一个全部bit的mask,在二进制表示中,它是11111111。
#define LMASK (FULLMASK << HALF_BITS_LENGTH)
// 这个宏表示左bits的mask,在二进制表示中,它是11110000。
#define RMASK (FULLMASK >> HALF_BITS_LENGTH)
// 这个数字表示右bits的mask,在二进制表示中,它表示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
// 这个数字表示将帅移动范围的行宽度。#include <stdio.h>#define HALF_BITS_LENGTH 4#define FULLMASK 255#define LMASK (FULLMASK << HALF_BITS_LENGTH)#define RMASK (FULLMASK >> HALF_BITS_LENGTH)#define RSET(b, n) (b = ((LMASK & b) |(n)))#define LSET(b, n) (b = ((RMASK & b) | (n << HALF_BITS_LENGTH)))#define RGET(b) (RMASK & b)#define LGET(b) ((LMASK & b) >> HALF_BITS_LENGTH)#define GRIDW 3int main(){ 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)); return 0;}方法二:
将帅总共有81种位置组合,为了便于计算,将位置组合num的范围计为[0, 80] 共81种。
a=num/9 b=num%9
if a%3 != b%3 符合 else 不符合
#include<stdio.h>int main(){unsigned char b=81; //b的范围:0~80while(--b){if(b/9%3 != b%9%3) printf("A = %d, B = %d\n", b/9+1, b%9+1);}return 0;}方法三:
利用位域
将一个字节划分成两个位域,分别存储将帅的位置a和b。
#include<stdio.h>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;}
参考资料:
http://my.oschina.net/cashlang/blog/57813
http://yangwei.blogbus.com/logs/1550489.html
- <<编程之美>>之中国象棋将帅问题
- 编程之美之中国象棋将帅问题
- 编程之美之中国象棋将帅问题
- 编程之美 - 中国象棋将帅问题
- 编程之美 - 读书笔记 - 中国象棋将帅问题
- 编程之美:中国象棋将帅问题
- 微软编程之美--中国象棋将帅问题
- 编程之美-中国象棋将帅问题
- 编程之美_002中国象棋将帅问题
- 编程之美-中国象棋将帅问题
- 编程之美---中国象棋将帅问题
- 编程之美二 : 中国象棋将帅问题
- 编程之美 -- 中国象棋将帅问题
- 编程之美 1.2 中国象棋将帅问题
- 编程之美1.2 中国象棋将帅问题
- 编程之美-中国象棋将帅问题
- 编程之美 1.2 中国象棋将帅问题
- 编程之美:中国象棋将帅问题
- 使position:fixed样式水平滚动的方法
- [转] java 执行sql脚本的3种方式 (ant,ibatis,ScriptRunner)
- Oracle建表常用数据类型详解
- HFS私人HTTP文件共享服务软件
- openstack 命令行管理十 - 密钥管理 (备忘)
- 编程之美-中国象棋将帅问题
- VirtualBox 虚拟机
- 内核——eCos内核概览
- Java控制流(如:标准输入输出)的注意事项
- 哈哈
- 四十三、迎接挑战,苦练内功,迎接春天的到来
- CFont与LOGFont 设置menu字体
- Android系统浏览器编译积累
- 华为内部狂转好文:有关大数据,看这一篇就够了