最近开始看编程之美这本书,里面有一道关于中国象棋将帅位置的简单问题,如下图所示,写一个程序输出将、帅的合法位置。

  

  分析与解法

  问题的本身并不复杂,只要把所有A、B 互相排斥的条件列举出来就可以完成本题的要 求。由于本题要求只能使用一个变量,所以必须首先想清楚在写代码的时候,有哪些信息需 要存储,并且尽量高效率地存储信息。稍微思考一下,可以知道这个程序的大体框架是:

  遍历A的位置 

    遍历B的位置  

      判断A、B的位置组合是否满足要求

        如果满足,则输出

  因此,需要存储的是A、B 的位置信息,并且每次循环都要更新。为了能够进行判断, 首先需要创建一个逻辑的坐标系统,以便检测 A 何时会面对 B。这里我们想到的方法是用 1~9的数字,按照行优先的顺序来表示每个格点的位置。这样,只需要用 模余运算就可以得到当前的列号,从而判断A、B 是否互斥。

  

  若题目要求只用一个变量,但是我们却要存储 A 和 B 两个子的位置信息,该怎么办呢?
  可以先把已知变量类型列举一下,然后做些分析。
  对于bool类型,估计没有办法做任何扩展了,因为它只能表示true和false 两个值;而 byte 或者 int 类型,它们能够表达的信息则更多。事实上,对本题来说,每个子都只需要 9 个数字就可以表达它的全部位置。
  一个8位的byte类型能够表达28=256个值,所以用它来表示A、B的位置信息绰绰有余, 因此可以把这个字节的变量(设为b)分成两部分。用前面的4 bit表示A的位置,用后面的 4 bit表示B的位置,那么4个bit可以表示16个数,这已经足够了。

  那么:如何使用bit级的运算将数据从这一byte变量的左边和右边分别存入和读出呢?

  大家容易想到的是对那个变量进行各种位运算,最后输出结果。

  但是其实C语言中还提供了一种存在于结构体中叫做位域的类型,因此程序就变得简单多了。关于位域更多的用法规则,详见:C位域

#include <stdio.h>
struct bf{
unsigned char a:;
unsigned char b:;
}i; /*定义位域结构*/
int main()
{
for(i.a = ; i.a <= ; i.a++)
{
for(i.b = ; i.b <= ; i.b++)
{
if(i.a % != i.b %)
printf("A = %d, B = %d\n", i.a, i.b);
}
}
return ;
}

  另一巧妙解法:

int main()
{
unsigned char i = ;
while(i--)
{
if(i/% != i%%)
printf("A = %d, B = %d\n", i/+, i%+);
}
return ;
}

位域 (Bit field)的更多相关文章

  1. 字节序转换与结构体位域(bit field)值的读取

    最近又遇到了几年前遇到的问题,标记一下. 对于跨字节位域(bit field)而言,如果数据传输前后环境的字节序不同(LE->BE,BE->LE),简单地调用(ntohs/ntohl/ht ...

  2. C语言位域

    转载自 http://tonybai.com/2013/05/21/talk-about-bitfield-in-c-again/ 再谈C语言位域 五 21 bigwhite技术志 bitfield, ...

  3. C语言位域——精妙使用内存

    参考链接  https://blog.csdn.net/yanbober/article/details/8697967  https://blog.csdn.net/Tommy_wxie/artic ...

  4. C学习笔记(6)--- 共用体,位域深入

    1.共用体(Union): 共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型.您可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值.共用体提供了一种使用相同的内存位置 ...

  5. 逻辑运算的妙用-Single Number

    题目:一个int的array,除了一个元素只有一个其余的都是两个,找到这一个的元素. 使用:逻辑运算 XOR异或运算 关于逻辑运算的总结[转] &&和||:逻辑运算符 &和|: ...

  6. NET设计规范(二) 命名规范

    http://blog.csdn.net/richnaly/article/details/6280294 第2章       命名规范 2.1.   大小写约定 2.1.1.    标识符的大小写规 ...

  7. 《C和指针》读书笔记

    1. 三字母词 三字母词即用三个字符合起来表示另一个字符,它可以使C环境在某些缺少一些必需字符的字符集上实现. ??( [ ??< { ??= # ??) ] ??> } ??/ \ ?? ...

  8. 字节序转换与结构体位域(bit field)值的读取 Part 2 - 深入理解字节序和结构体位域存储方式

    上一篇文章讲解了带位域的结构体,在从大端机(Big Endian)传输到小端机(Little Endian)后如何解析位域值.下面继续深入详解字节序,以及位域存储的方式. (1) 我们知道,存储数字时 ...

  9. 用EnumSet代替位域

    用EnumSet代替位域   如果一个枚举类型的元素主要用在集合中,一般使用int枚举模式,将2的不同倍数赋予每个常量: // Bit field enumeration constants - OB ...

随机推荐

  1. Elasticsearch 2.x.x版本如何安装bigdesk

    ES插件BigDesk安装 bigdesk支持的最新版本的ES是1.3.0 ... 1.3.x 然而想要在新版本ES上安装(2.x.x),项目中遇到过一些BUG,在ES在最新版本中有修复,所以采用了2 ...

  2. v1.0.2-2017.04.26

    v1.0.2-2017.04.26 增加支付宝.微信查询接口 增加订单轮询工程 增加网关下单后发起订单轮询业务流程 v1.0.1-2017.04.05 修复分页乱码bug 增加支付密码字段.商户服务器 ...

  3. 设计模式:解释器(Interpreter)模式

    设计模式:解释器(Interpreter)模式 一.前言 这是我们23个设计模式中最后一个设计模式了,大家或许也没想到吧,竟然是编译原理上的编译器,这样说可能不对,因为编译器分为几个部分组成呢,比如词 ...

  4. Hbase集群部署及shell操作

    本文详述了Hbase集群的部署. 集群部署 1.将安装包上传到集群并解压 scp hbase-0.99.2-bin.tar.gz mini1:/root/apps/ tar -zxvf hbase-0 ...

  5. define常量

    看手册说define定义的常量只允许: 仅允许标量和 null.标量的类型是 integer, float,string 或者 boolean. 也能够定义常量值的类型为 resource ,但并不推 ...

  6. EOJ-3300 奇数统计(高维前缀和)

    题目链接: https://acm.ecnu.edu.cn/problem/3300/ 题目大意: 给n个数,求在n个数中选两个数(可重复),使得这两个数的组合数是奇数,求总共有多少种取法. 解题思路 ...

  7. Cocos2d-x移植Android 常见问题处理办法

    1.函数.变量出现"could not be resolved "问题 出现此问题通常是没有找到cocos2d-x声明的头文件.在eclipse将cocos2d的头文件文件夹引入. ...

  8. JDBC(3)ResultSet

    ResultSet 在执行查询(select)时候使用 这是一个结果对象,该对象包含结果的方法但指针定位到一行时 调用Statement 对象的 executeQuery(sql)可以得到结果集 可以 ...

  9. MBTiles 离线地图演示 - 基于 Google Maps JavaScript API v3 + SQLite

    MBTiles 是一种地图瓦片存储的数据规范,它使用SQLite数据库,可大大提高海量地图瓦片的读取速度,比通过瓦片文件方式的读取要快很多,适用于Android.IPhone等智能手机的离线地图存储. ...

  10. OpenID Connect Core 1.0(二)ID Token

    2.ID Token(ID Token) OpenID Connect主要是对OAuth 2.0 能够使得终端用户通过ID Token的数据结构进行验证.当客户端和潜在的其他请求声明,ID Token ...