上图,将帅不能碰面,列出将帅不碰面的所有可能情况,要求:程序只能用一个只有8位的变量(#define这样的就不算了)

为了更加符合程序员的口味,给将帅位置编号如下:

0--1--2

|    |   |

3--4--5

|    |   |

6--7--8

输出将帅所有可能情况,(0,1)等等

--------------------------------------------------------------------------------------------------------------------------------------------------

思路一:程序框架应该如下,关键是怎么样用一个变量表示将帅位置.

遍历将位置

遍历帅位置

如果将帅位置不矛盾,输出

只用8位的变量,要表示2个数,看来可以试试位操作每个表示位置的变量4个位,4位可以表示0-15,足以!

方法一:

用位字段(为此还复习了位操作...http://www.cnblogs.com/jiayith/p/3500367.html)

如下:

#include <iostream>

using namespace std;

/*定义一个结构体,两个标签,各自4位,总共一个变量的话为8位*/
struct myBits
{
unsigned char a:; //4位可以表示0-15的值了
unsigned char b:;
}; int main(void)
{
myBits my; for (my.a=;my.a<=;my.a++)
{
for (my.b=;my.b<=;my.b++)
{
if (my.a%!=my.b%)
{
cout<<"("<<(int)my.a<<","<<(int)my.b<<")"<<endl;
}
}
} cin.get();
return ;
}

方法二:

既然都用了位字段,那位操作也应该没什么问题

用一个char,我的机器八位,左4位表示将的位置,右位表示帅的位置,关键是怎么给一个8位的char的左右半边赋值再获得左右半边的值.位操作!

#include <iostream>

/*下面几个宏用于掩码,在获得左右半边的值时用*/
#define FULLMASK 255 //
#define RMASK (FULLMASK>>4) //
#define LMASK (FULLMASK<<4) // /*下面是几个获得左右半边值的宏*/
#define GETR(t) (t&RMASK) //获得右半边4位的值,用掩码,掩盖住左半边的值,注意这个位操作不改变原有值
#define GETL(t) ((t&LMASK)>>4) //获得左半边4位的值,先掩盖右4位,再把值右移4位,注意这里要价格括号...我猜临时值放在某寄存器里 /*下面是设置左右半边值的宏*/
#define SETR(t,val) (t=(t&LMASK)|val)//((t=t&LMASK),(t=t|val)) //用十进制val设置右4位,但要保证val可以用4位表示,即val表示值的位在低4位.(这里先清空右四位,再与左4位全是0而右4位是值的val或)
#define SETL(t,val) (t=((t&RMASK)|(val<<4)))//((t=t&RMASK),(t=t|(val<<4))) //用十进制val设置左4位 (先清空左4位,再把val右边4位的值移动到左边,再与) int main(void)
{
using namespace std; unsigned char my; //注意这里一定要用无符号的,要不放最高位为1就麻烦了.... for (SETL(my,);(int)GETL(my)<=;SETL(my,(int)GETL(my)+))
{
for (SETR(my,);(int)GETR(my)<=;SETR(my,(int)GETR(my)+))
{
if (((int)GETL(my)%)!=((int)GETR(my)%))
{
cout<<"("<<(int)GETL(my)<<","<<(int)GETR(my)<<")\n";
}
}
} cin.get();
return ;
}

--------------------------------------------------------------------------------------------------------------------------------------------------

思路二:不用上面的程序模式了,换个思路.

将有9种情况,帅也有9种情况,组合起来共81种情况.

能不能用一个变量表示这81种情况,对于每个情况的值,获得将和帅的值???

可以!

将=0,帅=(0,1,2,3,4,5,6,7,8) 值可以从0到8

将=1,帅=(0,1,2,3,4,5,6,7,8) 值可以从9到17

将=2,帅=(0,1,2,3,4,5,6,7,8)  ..

将=3,帅=(0,1,2,3,4,5,6,7,8) ..

将=4,帅=(0,1,2,3,4,5,6,7,8)

将=5,帅=(0,1,2,3,4,5,6,7,8)

将=6,帅=(0,1,2,3,4,5,6,7,8)

将=7,帅=(0,1,2,3,4,5,6,7,8)

将=8,帅=(0,1,2,3,4,5,6,7,8) 值从72到80

即用一个八位的值val表示所以上述从0到80的81种情况,

val/9即将的值,val%9即帅的值,搞定!

#include <iostream>

int main(void)
{
using namespace std; char val=;
while (val<=)
{
if ((val/%)!=(val%%))
{
cout<<"("<<val/<<","<<val%<<")"<<endl;
}
val++;
} cin.get();
return ;
}

--------------------------------------------------------------------------------------------------------------------------------------------------

总结:

1.多角度看问题

2.C/C++位操作的强大,及几种位操作运算符的使用

编程之美 ---> 1.2中国象棋将帅问题的更多相关文章

  1. 1.2 中国象棋将帅问题进一步讨论与扩展:如何用1个变量实现N重循环?[chinese chess]

    [题目] 假设在中国象棋中只剩下将帅两个棋子,国人都知道基本规则:将帅不能出九宫格,只能上下左右移动,不能斜向移动,同时将帅不能照面.问在这样条件下,所有可能将帅位置.要求在代码中只能使用一个字节存储 ...

  2. 《编程之美》practice

    1.2.中国象棋将帅问题 要求:只用一个字节存储变量,输出将帅不照面的所有可能位置. 思路简单,就是穷举让将和帅不在同一列即可,用char高四字节和低四字节分别存储将和帅的位置,位置编号从1到9.代码 ...

  3. C/C++编程笔记:C语言打造中国象棋游戏,项目源代码分享!

    中国象棋是起源于中国的一种棋,属于二人对抗性游戏的一种,在中国有着悠久的历史.由于用具简单,趣味性强,成为流行极为广泛的棋艺活动. 它是中国棋文化,也是中华民族的文化瑰宝,它源远流长,趣味浓厚,基本规 ...

  4. JavaScript中国象棋程序(0) - 前言

    “JavaScript中国象棋程序” 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.希望通过这个系列,我们对博弈程序的算法有一定的了解.同时,我们也将构建出一个不错的中国象棋程序 ...

  5. JavaScript中国象棋程序(4) - 极大极小搜索算法

    "JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第4节. 这一系列共有9个部分: 0.JavaScript中国象 ...

  6. C/C++游戏项目:中国程序员一定要会的中国象棋教程

    中国象棋是中国一种流传十分广泛的游戏. 下棋双方根据自己对棋局形式的理解和对棋艺规律的掌握,调动车马,组织兵力,协调作战在棋盘这块特定的战场上进行着象征性的军事战斗. 象棋,亦作"象碁&qu ...

  7. <<编程之美>>1.2读后有感

    问题提出 中国象棋的"将","帅"问题,他俩不能在一条直线上.求出他们的合法位置,并且只能用一个变量. 分析 一头雾水,不明所以.往下看了下,感觉像是程序员为难 ...

  8. BZOJ 1801中国象棋 DP

    1801: [Ahoi2009]chess 中国象棋 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1426  Solved: 826[Submit][ ...

  9. 【编程之美】2.5 寻找最大的k个数

    有若干个互不相等的无序的数,怎么选出其中最大的k个数. 我自己的方案:因为学过找第k大数的O(N)算法,所以第一反应就是找第K大的数.然后把所有大于等于第k大的数取出来. 写这个知道算法的代码都花了2 ...

随机推荐

  1. [AngularJS] $http cache

    By default your HTTP requests with the $https service in Angular are not cached. By setting some opt ...

  2. IOS使用APNS推送Payload字节数限制导致推送不成功

    这2天须要在推送上加上脚本,找到了badge方法能够加脚本.加上后可是怎么推送也不成功.郁闷了好久.在网上查找相关资料. 最终被我找到原因: "Payload--最多256bytes. &q ...

  3. UNIX基础知识之文件和目录

    程序清单1-1 列出一个目录中的所有文件(ls命令的简要实现): [root@localhost unix_env_advance_prog]# cat prog1-.c #include " ...

  4. cocos2d-x之MoonWarriors用c++实现

    玩了sample里面的cocos2d-html5的MoonWarriros,感觉效果做得挺不错的,但是源代码是javascript,鄙人又不会这门语言. github上也有别人贡献的c++代码,不过还 ...

  5. 分享一个java线程专栏

    专栏 : java线程基础 转载自 http://blog.csdn.net/column/details/yinwenjiethread.html 专栏内容: 1.线程基础:线程(1)--操作系统和 ...

  6. Url几个常用的函数

    parse_url() 本函数解析一个 URL 并返回一个关联数组,包含在 URL 中出现的各种组成部分. 本函数不是用来验证给定 URL 的合法性的,只是将其分解为下面列出的部分.不完整的 URL ...

  7. MSP430常见问题之复位系统类

    Q1:请问msp430 怎么手动复位啊?是不是连到RST/NMI 上?但是这个脚不是和JTAG 连吗?我看到一些资料上说复位的话还要上拉电阻或者复位电路.A1:JTAG 功能只在下载程序时候使用,正常 ...

  8. hdu 4455 动态规划

    思路:用sum[i]表示区间长度为i的不相同数的个数和,假使所有的数都不相同,那么sum[i]=sum[i-1]+n-i+1-later[i-1]; later[i-1]表示的是序列最后面的长度为i- ...

  9. 通过使用精简客户端,且不需要安装的客户端,配合PLSQL连接oracle数据库

    通过使用精简客户端,且不需要安装的客户端,配合PLSQL连接oracle数据库. 首先下载安装包在Oralce官方网站上下载Oracle Instantclient Basic package.地址如 ...

  10. (转)linuxmint,ubuntu 下修改guake宽度方法

    之前在网上找到修改guake.py的方式,但是我一直没能找到guake.py的文件,弄的我纠结,后来找到这个文章,这个确实是有效果的 Ubuntu12.04上Guake在唤出的时候滚动条会消失,主要原 ...