【编程之美读书笔记】中国象棋将帅问题

来源:互联网 发布:尼康全站仪导入数据 编辑:程序博客网 时间:2024/04/29 03:34

问题描述:

根据中国象棋的规则,将和帅被限制在己方田字格中运动,并且不能碰面,求出将帅的所有合法位置。

要求:代码中只用一个变量。


问题分析:


给将和帅的位置信息进行编号,如上图所示。然后,

遍历A的位置

遍历B的位置

     判断A和B的位置是否满足要求

     如果满足,输出

问题解答:

编程之美中的第一种解法是将一个BYTE变量拆成两部分,前面4位代表将能走的位置,后面4位代表帅能走的位置,利用位操作来得到将和帅的合法位置。但第一种操作比较复杂,我也没有仔细看。第三种解法和第一种解法的思想相同,只不过用了位域的概念(位域具体可参见http://blog.csdn.net/ruan875417/article/details/43372093),但操作变得简单。因此,在这里我把它当做方法一。

方法一:

#include<iostream>using namespace std;struct{    unsigned char a:4;    unsigned char b:4;}i;int main(){    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)             printf("a=%d b=%d\n",i.a,i.b);        system("pause");    return 0;}

第二种解法是比较奇妙的,先给出完整的代码。

方法二:

#include<iostream>#include <windows.h>using namespace std;int main(){    BYTE i=81;    while(i--){       if(i/9%3==i%9%3)          continue;       printf("%d %d\n",i/9+1,i%9+1);    }    system("pause");    return 0;}

将和帅各自有9个位置可以走,因此我们要验证9*9=81种位置关系。其次我们要知道i/9和i%9代表的意思。我们知道一个整数n=(n/9)*9+n%9,在i从81到0的变化过程中,n/9相当于外循环,n%9相当于内循环,这样我们就用一个变量同时表示了将和帅的位置。

 

扩展:如何用一个变量来表示三重循环,四重循环。。。n重循环。

对于a*b=i,

用如下公式展开:

loop1=i%b,

loop2=(i/b)%a

 

对于三重循环,可以看做a=m*n,

用公式展开:

loop1=i%b,

loop2=(i/b)%n,

loop3=((i/b)/n)%m

 

由此得到n重循环的公式:

设an* an-1*……* a2* a1=N,

loop1=i% a1

loop2=(i/ a1)% a2,

loop3=(i/( a1a2))%a3

……

loopn=(i/( a1a2…an))%an

 

最后,附上用一个变量实现三重循环的代码

#include<iostream>#include <windows.h>using namespace std;int main(){    BYTE i=5*4*3;    while(i--){       printf("n=%d i=%d j=%d k=%d \n",i,(i/(3*4))%5,(i/3)%4,i%3);    }    system("pause");    return 0;}
运行结果:




0 0
原创粉丝点击