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

  

  分析与解法

  问题的本身并不复杂,只要把所有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. ELK_Elastic Search和kibana版本对应关系

    https://www.elastic.co/downloads/past-releases/kibana-5-0-0 https://www.elastic.co/downloads/past-re ...

  2. Oracle 12c logminer测试

    首先开启归档:SQL> archive log list   Database log mode              Archive ModeAutomatic archival     ...

  3. 【深入理解JAVA虚拟机】第三部分.虚拟机执行子系统.4.类加载及执行子系统的案例与实战

    1.概述 在Class文件格式与执行引擎这部分中 : 用户不能控制的:Class文件以何种格式存储,类型何时加载. 如何连接,以及虚拟机如何执行字节码指令等都是由虚拟机直接控制的行为 用户能控制的:字 ...

  4. ZT Android布局】在程序中设置android:gravity 和 android:layout_Gravity属性

    Android布局]在程序中设置android:gravity 和 android:layout_Gravity属性 分类: [Android基础] 2011-04-19 16:06 54739人阅读 ...

  5. sparsity and density

    转:http://searchdatamanagement.techtarget.com/definition/sparsity-and-density 查了一下定义,以免会写错 Sparsity a ...

  6. 什么是SAP GUI的client

    我们用SAPGUI登录某个系统时,除了用户名和密码外,还要指定一个必填字段client: 这个client是什么东东? 看文档: SAP Client is the highest hierarchi ...

  7. C 语言实现多态的原理:函数指针

    C语言实现多态的原理:函数指针 何为函数指针?答案:C Programming Language. 能够查阅下,从原理上来讲,就是一个内存地址.跳过去运行相应的代码段. 既然如此,在运行时决定跳到哪个 ...

  8. luogu P2617 Dynamic Rankings(分块,n <= 1e4)

    嘟嘟嘟 带修改区间第k大. 然而某谷把数据扩大到了1e5,所以用分块现在只能得50分. 分块怎么做呢?很暴力的. 基本思想还是块内有序,块外暴力统计. 对于修改,直接重排修改的数所在块,时间复杂度O( ...

  9. 利用SPF记录缺失发送伪造邮件

    SPF,也就是 Sender Policy Framework 的缩写,是一种以IP地址认证电子邮件发件人身份的技术,是非常高效的垃圾邮件解决方案. 如何查询所属域名邮箱的SPF记录? 查询的结果,从 ...

  10. 3springboot:springboot配置文件(配置文件、YAML、属性文件值注入<@Value、@ConfigurationProperties、@PropertySource,@ImportResource、@Bean>)

    1.配置文件: springboot默认使用一个全局配置文件 配置文件名是固定的   配置文件有两种(开头均是application,主要是文件的后缀): ->application.prope ...