【题目】

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

【分析】

3种方案:

1)位运算实现1个byte存入和读取2个变量。

2)使用位域把几个不同的对象用一个字节的二进制位域来表示。比如

 C++ Code 
1
2
3
4
5
 
struct
{
    ;
    ;
} i;

3)使用1个变量表达2重循环。后面将会重点讨论该方案。(思考:如何用1个变量实现N重循环?)

【位运算】

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 
/*
    version: 1.0
    author: hellogiser
    blog: http://www.cnblogs.com/hellogiser
    date: 2014/6/24
*/
#include<stdio.h>

#define LMASK (FULLMASK << HALF_BITS_LENGTH)
#define RMASK (FULLMASK >> HALF_BITS_LENGTH)
#define RSET(b,n) (b = (b & LMASK) | (n))
#define LSET(b,n) (b = ((b & RMASK) | ((n) << HALF_BITS_LENGTH)))
#define RGET(b) (b & RMASK)
#define LGET(b) ((b & LMASK)>>HALF_BITS_LENGTH)

void Solution1()
{
    unsigned char b;
    )))
    {
        ))
        {
            if(LGET(b) % GRIDW != RGET(b) % GRIDW)
            {
                printf("A=%d,B=%d\n", LGET(b), RGET(b));
            }
        }
    }
}

位域

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
/*
    version: 1.0
    author: hellogiser
    blog: http://www.cnblogs.com/hellogiser
    date: 2014/6/24
*/
struct
{
    ;
    ;
} i;

void Solution2()
{
    ; i.a++)
        ; i.b++)
            ) // column not equal
                printf("%d,%d\n", i.a, i.b);
}

【单个变量】

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
/*
    version: 1.0
    author: hellogiser
    blog: http://www.cnblogs.com/hellogiser
    date: 2014/6/24
*/
void Solution3()
{
    ;
    while(i--)
    {
        // i = 9*a+b, a = i/9, b = i%9
)
            continue;
        printf();
    }
}

“将”和“帅”各在自己的3*3的格子间里面走动,我们共需要验证9*9=81种位置关系,这也是i=81的由来。此外我们要明白 i/9和i%9的含义。我们知道,整数i可以由部两分组成,即i=(i/9)*9+i%9 。我们注意到,在i从81到0变化的过程中,i%9的变化相当于内层循环,i/9的变化相对于外层循环。

【扩展】

如何用1个变量实现N重循环?

先看个简单例子,1个变量实现2重循环。

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
/*
    version: 1.0
    author: hellogiser
    blog: http://www.cnblogs.com/hellogiser
    date: 2014/6/24
*/
void LoopWith2Variables()
{
    unsigned char i, j;
    ; i++)
        ; j++)
            printf("%d,%d", i, j);
}

void LoopWith1Variable()
{
    ;
    while(val--)
    {
        printf();
    }
}

【总结】

对于 a*b = i ,我们可以用如下公式展开:

loop1=i%b;

loop2=(i/b)%a

其中loop1是内层循环,loop2是外层循环。

由此可以得出N重时的公式,假设 an * a(n-1) * ....... * a3 * a2 * a1 = N

loop1=N%a1

loop2=(N/(a1))%a2

loop3=(N/(a1a2))%a3

.....

loopN=(N/(a1a2.....a(n-1)))%an

【参考】

http://blog.csdn.net/kabini/article/details/2256421

http://blog.csdn.net/silenceburn/article/details/6133222

http://blog.csdn.net/zhongkeli/article/details/8779168

http://www.cnblogs.com/python27/archive/2012/04/10/2441114.html

【本文链接】

http://www.cnblogs.com/hellogiser/p/chinese-chess.html

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

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

    上图,将帅不能碰面,列出将帅不碰面的所有可能情况,要求:程序只能用一个只有8位的变量(#define这样的就不算了) 为了更加符合程序员的口味,给将帅位置编号如下: 0--1--2 |    |   ...

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

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

  3. JavaScript中国象棋程序(5) - Alpha-Beta搜索

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

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

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

  5. JavaScript中国象棋程序(1) - 界面设计

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

  6. JavaScript中国象棋程序(2) - 校验棋子走法

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

  7. JavaScript中国象棋程序(3) - 电脑自动走棋

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

  8. JavaScript中国象棋程序(6) - 克服水平线效应、检查重复局面

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

  9. JavaScript中国象棋程序(7) - 置换表

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

随机推荐

  1. Mysql常出现的问题

    1.mysql如何导入.txt文件?load data local infile 'D:\\data.txt' into table 表名 fields terminated by '\t';2.my ...

  2. String类的常用方法

    package stringUse; public class StringUse { public static void main(String[] args) { //获取 //indexOf, ...

  3. MySQL里面的子查询实例

    一,子选择基本用法 1,子选择的定义 子迭择允许把一个查询嵌套在另一个查询当中.比如说:一个考试记分项目把考试事件分为考试(T)和测验(Q)两种情形.下面这个查询就能只找出学生们的考试成绩 selec ...

  4. Applying Eigenvalues to the Fibonacci Problem

    http://scottsievert.github.io/blog/2015/01/31/the-mysterious-eigenvalue/ The Fibonacci problem is a ...

  5. FCKeditor漏洞利用

    FCKeditor漏洞利用 查看编辑器版本 FCKeditor/_whatsnew.html fckeditor/editor/dialog/fck_about.html —————————————— ...

  6. 防止ajax请求重发

    debounce  ajax请求,防止用户点击过快造成重发 按钮disabled处理,显示loading,防止用户失去耐心,重复点击 表单提交也可以同样处理.

  7. .NET平台上的Memcached客户端介绍

    早上接到一个任务,需要对Linux服务器的Memcached的update操作进行性能测试,我发现我是一个典型的“手里拿着锤子, 就把所有问题都当成钉子”的人.我第一个念头就是,上Memcached的 ...

  8. @suppressWarnings解释

    J2SE 提供的最后一个批注是 @SuppressWarnings.该批注的作用是给编译器一条指令,告诉它对被批注的代码元素内部的某些警告保持静默. 一点背景:J2SE 5.0 为 Java 语言增加 ...

  9. MySQL日期数据类型、MySQL时间类型使用总结

    MySQL:MySQL日期数据类型.MySQL时间类型使用总结 MySQL 日期类型:日期格式.所占存储空间.日期范围 比较. 日期类型 存储空间 日期格式 日期范围 ------------ --- ...

  10. C++中的异常处理(三)

    C++中的异常处理(三) 标签: c++C++异常处理 2012-11-24 23:00 1520人阅读 评论(0) 收藏 举报  分类: 编程常识(2)  版权声明:本文为博主原创文章,未经博主允许 ...