下面是书中给出的第二个方法:

#include<stdio.h>
#define BYTE unsigned char
int main(void)
{
BYTE i = 81;
while(i--)
{
if((i / 9) % 3 == (i % 9) % 3)
continue;
printf("A = %d, B = %d\n", i /9 + 1, i%9 + 1);
}
return 0;
}

“将”和“帅”各在自己的3*3的格子间里面走动,我们共需要验证9*9=81种位置关系,这也是i=81的由来。此外我们要明白 i/9和i%9的含义。我们知道,整数i可以由部两分组成,即var=(var/9)*9+var%9 ,其中var<n。我们注意到,在i从81到0变化的过程中,var%9的变化相当于内层循环,var/9的变话相对于外层循环。这样,作者就巧妙地用一个变量i同时获得了两个变量的数值。

可以把变量i想象成一个两位九进制的变量,而i在计算机中存储的值是i的十进制表示。则i/9的计算机处理结果,即结果直接去掉小数点后部分的结果即是此九进制数的第二位,而i%9即是此九进制数的个位。本程序用此九进制数的第二位保存A的位置,个位表示B的位置。最大值为88,即为十进制的80.程序从十进制的80,即九进制的88遍历到十进制的0,即九进制的0。将符合条件的位置全部输出。

问题扩展:如何利用一个变量达到三重循环的效果。也就是说,如果给定下面的循环:

int counter = 0;

for( int i = 0; i < 5; i++ )

for( int j = 0; j < 4; j++ )

for( int k = 0; k < 3; k++ )

{

System.out.println("counter="+counter+"\t, i="+i+", j="+j+", k="+k);

counter++;

}

其结果如下:

counter=0 , i=0, j=0, k=0

counter=1 , i=0, j=0, k=1

counter=2 , i=0, j=0, k=2

counter=3 , i=0, j=1, k=0

counter=4 , i=0, j=1, k=1

....中间略

counter=59  , i=4, j=3, k=2

问题是

(1)我们如何用一个打印出相同的结果?

(2)如果是N重循环呢?

面对第一个问题,实际上就是对原始的中国象棋将帅问题进行了一个扩展,即在棋盘上添加一个“王”,其行走规则和将帅 一样。于是棋盘变成了三国争霸:-) ,将帅王可以走动的格子数分别为3、4、5,它们之间的互斥条件可以按需要设定。

这时,就需要只用一个变量遍历一个三重循环。直观的方法是像方法一那样把一个4字节的INT拆开来用。

我这里只关注方法二。

只用一个变量解决扩展的中国象棋将帅问题,我们的代码应该是如下的样子:

int var = 3*4*5;

while( var-- )

{

if( /** 冲突条件 **/ )//发生冲突

  continue;

else

printf(/** 打印可行的位置 **/);    }

在冲突条件中,我们需要知道var取得某个特定的值(即第var+1次循环)的时候的i,j,k分别是多少(这样我们才能判定将帅位置是否冲突)

从上例的结果中我们可以看到,counter的值(即当前的循环次数)和三元组(i,j,k)是一一对应的,越是外层的循环变化越慢,他们满足什么关系呢?

k的取值最好确定,我们都知道是var%3。

在原始的将帅问题中我们知道,j的值应该是 var/3,但是由于j上面还有一层循环,就需要做些调整,变成var/3%4

最外层循环i的值则为(var/(3*4))%5.           即:

k=var%3      //其下没有循环了

j=var/3   //其下有几个循环长度为3的循环

i=var/(3*4). //其下有几个循环长度为3*4的循环

于是4重循环的公式我们也可以轻松得出:

for( int i = 0; i < 5; i++ )

  for( int j = 0; j < 4; j++ )

    for( int k = 0; k < 3; k++ )

      for( int p = 0; p < 3; p++ )

p=var%2 //其下没有循环了

k=var/2      //其下有几个循环长度为2的循环

j=var/(2*3)) //其下有几个循环长度为2*3的循环

i=var/(2*3*4)//其下有几个循环长度2*3*4的循环

下面就是一个变量实现三重循环

int var = 2*3*4*5;

while( var-- > 0)

{

System.out.println("var="+var+" , i="+((var/(2*3*4))%5)+

                              ", j ="+((var/(2*3))%4)+",

                              k="+((var/2)%3)+",

                              p="+var%2);

}

结果是:

var=119 , i=4, j=3, k=2, p=1

var=118 , i=4, j=3, k=2, p=0

var=117 , i=4, j=3, k=1, p=1

...中间略

var=5 , i=0, j=0, k=2, p=1

var=4 , i=0, j=0, k=2, p=0

var=3 , i=0, j=0, k=1, p=1

var=2 , i=0, j=0, k=1, p=0

var=1 , i=0, j=0, k=0, p=1

var=0 , i=0, j=0, k=0, p=0

N重循环原理也是一样,就不再赘述了。

转载于:https://www.cnblogs.com/gaowanchen/p/3618228.html

编程之美——1.2 中国象棋将帅问题(转)相关推荐

  1. 编程之美 1.2 中国象棋将帅问题

    编程之美 1.2 中国象棋将帅问题 版权所有, 禁止转载, 如有需要, 请站内联系. 本文地址: http://blog.csdn.net/caroline_wendy/article/details ...

  2. 编程之美-中国象棋将帅问题

    废话不多说,上代码 代码 /************************************************************************编程之美1.2中国象棋将帅的 ...

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

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

  4. 编程之美- 中国象棋将帅问题

    2019独角兽企业重金招聘Python工程师标准>>> 问题描述: 在中国象棋规则中,将和帅规定只能在田字格中移动,且将和帅是不能碰面的,请求解出所有可能的符合规则的将帅位置. 限制 ...

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

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

  6. 中国象棋将帅问题(一)

    题记--开始学习编程之美,第一次写博客记录自己的编程心得,希望自己不断进步,做一个踏实的codeman.通过博客能够记录每次的编程体会,将一些重要的知识点进行标注,便于日后查看复习.如果,有朋友能够从 ...

  7. 中国象棋将帅问题的一种解法

    "中国象棋将帅问题"的一种解法 在<编程之美:微软技术面试心得>一书中,看到这样一道"中国象棋将帅问题": 下过中国象棋的朋友都知道,双方的&quo ...

  8. 【编程之美】中国象棋将帅问题

    问题描述 在中国象棋里将和帅是不能碰面的,如下图所示,当将位于d10时,帅就不能在d1,.d2.d3.请写一个程序,输出将.帅所有的合法位置.要求在代码中仅用一个变量. 如果只是输出将.帅的合法位置, ...

  9. 编程之美 - 中国象棋将帅问题

    下过中国象棋的朋友都知道,双方的"将"和"帅"相隔遥远,并且它们不能照面.在象棋残局中,许多高手能利用这一规则走出精妙的杀招.假设棋盘上只有"将&qu ...

最新文章

  1. 约瑟夫环双向链表c语言实,双向链表与约瑟夫环代码
  2. c语言编程将图片上下翻转,C语言实现矩阵翻转(上下翻转、左右翻转)
  3. (经典)Hibernate多对多关系映射(五)
  4. 计算机网络互联网技术实验报告,2013计算机网络技术与应用.实验报告01
  5. 2021年B站创作者生态报告
  6. 计算机美国学游戏开发,【工程与计算机】一石二鸟:开发游戏为申美国名校加码...
  7. java变量自增题的分解08251944
  8. 设计作品展示类网站,设计提升调性必不可少
  9. SELinux系列(七)——SELinux安全上下文的修改和设置(chcon和restorecon命令)
  10. 公司使用 Qt 到底要不要付费?| 博文精选
  11. Linux下打开Android调试器DDMS的方法
  12. JSON Editor for Mac(JSON编辑器)
  13. 2013年新交规科目二考试实录(北京京东驾校)
  14. win10计算机打开速度慢,win10电脑速度突然很慢怎么处理
  15. 常用web服务器架构理解
  16. 403 forbidden 错误解决方案
  17. 一个公式,把营销从玄学变回科学
  18. 从我那句名言“系统上线之日,需求开始之时”谈大型信息化系统建设的那些坑
  19. Main.obj : error LNK2019: 无法解析的外部符号 _Direct3DCreate9@4,该符号在函数 long __cdecl InitD3D(struct HWND__ *)
  20. Git入门|Git的基本用法(一)

热门文章

  1. 如何一键制作css精灵图?
  2. 还不了解什么是商业智能(BI)?看完这篇文章就懂了
  3. ubuntu16.4离线安装显卡驱动
  4. 身份证最后一位验证[python]
  5. 虚拟机与Java虚拟机
  6. redis 8.Redis持久化之RDB (如何触发RDB快照;rdb备份恢复)
  7. PS制作圆角透明图片
  8. 我跟敏捷开发的故事--三面墙
  9. Linux操作系统各发行版ISO镜像下载
  10. RGB 颜色透明16进制表示