http://blog.csdn.net/pipisorry/article/details/36380669

问题:下过中国象棋的朋友都知道,双方的“将”和“帅”相隔遥远,并且它们不能照面。在象棋残局中,许多高手能利用这一规则走出精妙的杀招。假设棋盘上只有“将”和“帅”二子(如图1-3所示)(为了下面叙述方便,我们约定用A表示“将”,B表示“帅”):

AB二子被限制在己方3×3的格子里运动。例如,在如上的表格里,A被正方形{d10f10d8f8}包围,而B被正方形{d3f3d1f1}包围。每一步,AB分别可以横向或纵向移动一格,但不能沿对角线移动。另外,A不能面对B,也就是说,AB不能处于同一纵向直线上(比如Ad10的位置,那么B就不能在d1d2以及d3)。

请写出一个程序,输出AB所有合法位置。要求在代码中只能使用一个变量

分析:

题目中仅仅是要求判断将与帅是否照面,而将与帅只能在各自的9个位置移动,因而只需要形式化1~9这9个数字。

此题的解法一中的常规解决手段,即是位操作。一般是定义一系列的掩码(masks)——可以用宏定义,或者枚举类型——来完成。

参考代码:

/****************************************************************************/
/*  1.2中国象棋将帅问题     皮皮 2014-7-1                 */
/****************************************************************************/
#include <stdio.h>typedef struct bitField{unsigned char a:4;unsigned char b:4;
}bit;void chessTest1(){char column = 1;for(; column <=3 ; column ++){            //A的列选for(; column <= 9; column += 3){    //A(和B)的行选printf("A = %d, B = %d\n", column, column%3 + 1);printf("A = %d, B = %d\n", column, column%3 + 1 + 3);printf("A = %d, B = %d\n", column, column%3 + 1 + 6);printf("A = %d, B = %d\n", column, (column + 1)%3 + 1);printf("A = %d, B = %d\n", column, (column + 1)%3 + 1 + 3);printf("A = %d, B = %d\n", column, (column + 1)%3 + 1 + 6);}column -= 9;}
}void chessTest2(){char i = 81;while(i--){if(i/9 % 3 == i % 9 %3)    //i/9(A的编号-1[0~8]) % 3(A的列); i%9(B的编号-1[8~0]) %3continue;           //同列则continueprintf("A = %d, B = %d\n",i/9 + 1, i%9 + 1);}
}void chessTest3(){bit i;   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)    //A B不同列printf("A = %d, B = %d\n", i.a, i.b);
}void main(){<span style="font-family: Arial, Helvetica, sans-serif;">     chessTest3();</span><span style="font-family: Arial, Helvetica, sans-serif;">}</span>

说明:

1.看chessTest1,其实只需要printf就可以输出正解,只要AB不同列就可以,共3*3 * 2*3 = 54种情况

2.chessTest2比较不好想,只要注意AB编号不能同时相同(if判断语句中)且AB不同列时才输出就可以

<span style="font-size:14px;">3.chessTest3使用了位域方法,位域知识参见:http://blog.csdn.net/pipisorry/article/details/36220851</span>

位域的概念《C程序设计语言》用了一页纸介绍,说明了应用场合主要是为了节省空间或直接访问位,应用场景如编译器的符号表以及一些硬件的驱动程序。网络开发、信息编码压缩解压缩、位图等方面可能还会用到,其余的场景多半会去讨论怎么节省时间开销,让程序运行的更加高效。

此外还有一种位读写方式是STL库中提供的泛型类bitset,它支持对位赋值的操作,也支持整体的位运算,最方便的是输入输出流被重载,很容易查看对应的位是否被置正确。相比于位域,bitset不能支持局部几个比特位的访问,而这正是位域的优势。不过对将与帅的问题,要求一个字节,而bitset基本的对齐是4个字节,所以可能不符合题目要求,不过对于其它的位操作场合却是一种很好的选择。

位域的概念《C程序设计语言》用了一页纸介绍,说明了应用场合主要是为了节省空间或直接访问位,应用场景如编译器的符号表以及一些硬件的驱动程序。我想做网络开发、信息编码压缩解压缩、位图等方面可能还会用到,其余的场景多半会去讨论怎么节省时间开销,让程序运行的更加高效。
另解:

要将一个变量i拆成两个,可以根据它的二进制表示分别取出连续几位,比如第0-3位和第4-7位,读变量时,取出变量i相应的几位,存变量时,再更新变量i的对应几位。另外,利用位置的对称性,可以一次输出两个,减少循环次数。

下面的代码和解法一类似,但是一次输出两个,减少了循环次数,并且没有用到除法(不考虑C++ IO效率的影响)

  //外层循环变量b使用i的第4-7位,初始值为1,最大值为8。//内层循环变量a使用i的第0-3位,初始值为b+1,最大值为9。for (unsigned i = 0x10; i < 0x90; i += 0x10)for (i= (i & 0xF0) | (i >> 4); (++i & 0xF) < 10; )if (((i & 0xF) - (i >> 4)) != 3 && ((i & 0xF) - (i >> 4)) != 6)std::cout << "A=" << (i >> 4)  << ", B="<< (i & 0xF) << "\n"<< "A=" << (i & 0xF) << ", B="<< (i >> 4)  << "\n";
from:http://blog.csdn.net/pipisorry/article/details/36380669
ref:http://www.cnblogs.com/flyinghearts/archive/2010/09/08/1821042.html

编程之美读书笔记1.2——中国象棋将帅问题相关推荐

  1. 中国象棋将帅问题java_编程之美读书笔记1.2——中国象棋将帅问题

    http://blog.csdn.net/pipisorry/article/details/36380669 问题:下过中国象棋的朋友都知道,双方的"将"和"帅&quo ...

  2. 【编程之美/读书笔记】Chapter 1 游戏之乐

    这里就不写每个问题的题目了,只是记录一下自己的总结和心得. 1.1 让CPU占用率听你指挥 这个题目我刚接触的想法是和多核多线程要扯上关系的,因为自己写个死循环只能跑到CPU 35%左右的占用率,但是 ...

  3. 编程之美 - 读书笔记 - 卖书折扣问题的贪心解法

    <编程之美>读书笔记(四):卖书折扣问题的贪心解法 每 次看完<编程之美>中的问题,想要亲自演算一下或深入思考的时候,都觉得时间过得很快,动辄一两个小时,如果再把代码敲一遍的话 ...

  4. Java并发编程之美读书笔记-并发编程基础2

    2019独角兽企业重金招聘Python工程师标准>>> 1.线程的通知与等待 Java中的Object类是所有类的父亲,鉴于继承机制,Java把所有类都需要的方法放到了Object类 ...

  5. 编程之美读书笔记2.1—求二进制数中1的个数

    解法一: 可以举一个8位二进制的例子.对于二进制操纵,我们除以一个2,原来数字就会减少一个0(向右移一位).如果除的过程中有余,那么久表示当前位置有一个1. 以10100010为例: 第一次除以2时, ...

  6. 编程之美--读书笔记--返回一个数组中所有元素被第一个元素除的结果

    笔试题目1:写一个函数,返回一个数组中所有元素被第一个元素除的结果 很多人会想到如下: void DivAarry(int *pArray,int size) { for(int i=size-1;i ...

  7. 编程之美读书笔记之-高效率的安排见面会

    问题一: n个同学,分别对m个招聘见面会感兴趣.为了满足所有学生的要求,hr希望让每个同学都能参加自己所有感兴趣的见面会.然后每个见面会的时间为t.问如何安排见面会能够使得所有见面会总的时间最短. 建 ...

  8. 编程之美 - 读书笔记 - 烙饼问题与搜索树

    前 面已经写了一些关于烙饼问题的简单分析,但因为那天太累有些意犹未尽,今天再充实一些内容那这个问题研究透.我想,通过这篇文章,我们就可以把这一类问题 搞懂.再遇到优化问题,如果我们想不到别的办法,就可 ...

  9. 编程之美读书笔记_1.1_让CPU占用率曲线听你指挥

    题目:写一个程序,让用户来决定Windows任务管理器(Task Manager)的CPU占用率.程序越精简越好,计算机语言不限.例如,可以实现下面三种情况:   1.    CPU的占用率固定在50 ...

  10. 中国象棋将帅问题java_编程之美:中国象棋将帅问题

    Author: Fox 晚上没有加班,打游戏打到9点过,后面就又看了一道<编程之美>的题目<中国象棋将帅问题>. 题目:下过中国象棋的朋友都知道,双方的"将" ...

最新文章

  1. 黄聪:原生js的音频播放器,兼容pc端和移动端(原创)
  2. mybatis-mysql常用操作
  3. 生信人写程序2. Editplus添加Perl, Shell, R模板和语法高亮
  4. 命令行参数 - 和 -- 的区别
  5. 青春环游记 | 雪中悍刀行之卡尔曼的鱼【回顾 2021,展望 2022】
  6. Linux 进程通信fifo,Linux 进程通信之FIFO的实现
  7. 谈一谈RDD 持久化的三个算子:cache、persist、checkpoint
  8. 第五章 列表、元组和字符串[DDT书本学习 小甲鱼]【2】
  9. 第一章 Java代码执行流程
  10. networkxpdf_1 NetworkX概述
  11. java.lang.SecurityException: class “org.bouncycastle.asn1.DERObject“‘s signer information does not m
  12. Matlab数字孪生
  13. Atitit mybatis 3 3.2 3.3  3.4 新特性attilax总结
  14. 多个端口指定多个目录。花生壳多个域名多个网站
  15. 如何制作一个蓄力跳的功能
  16. 独立双(N)拥塞窗口的TCP单边加速思想
  17. java 读取hdfs上的文件内容
  18. mysql sql 取年份_mysql – 从时间戳sql中获取年份
  19. QT 读ini配置文件
  20. C++的lib文件到底是什么

热门文章

  1. Leetcode题解(十九)
  2. 遍历josn的三种方式
  3. 11.消息摘要算法之MD5
  4. Uva 10306 e-Coins
  5. 北京上海等昨天大规模断网 专家称与太阳无关
  6. 写于Silverlight整装待发之际【瞿杰】
  7. 在ASP.NET中显示Linq To SQL输出的SQL语句
  8. Visual Studio基于CMake配置opencv1.0.0、opencv2.2
  9. 忙了好一阵子了 才记起来我的博客园
  10. C++.Net在Release方式下单步调试时需要修改一些设置,否则变量会有错位或乱码,切记!...