中国象棋将帅问题

中国象棋将帅问题

flyfish 2015-8-11

问题引自 《编程之美》中国象棋将帅问题

将帅每一着只许走一步,前进、后退、横走都可以,但不能走出“九宫”,被限制在3×3的格子里运动。将和帅不准在同一直线上直接对面。

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

约定用a表示“将”,b表示“帅”

一个解法是关于位操作 跳过

原文提供解法一

struct {
    unsigned char a:4;
    unsigned char b:4;
} 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)
                printf("A=%d,B=%d\n",i.a,i.b);

思路是将一个变量拆成两部分

原文提供解法二

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);
}

问题转换

有个两位数m,十位上的数是a,个位上是b

每个位上的数只能是从1到9组成,则共有9*9=81种组成方式

a[1,9]={a|1?a?9}

b[1,9]={b|1?b?9}

两位数数列

11、12、13、14、15、16、17、18、19

21、22、23、24、25、26、27、28、29

当下标从0开始时,各个数就减1, 就完全成了一个9进制的数,满9进1

10、11、12、13、14、15、16、17、18

20、21、22、23、24、25、26、27、28

10进制的81 ,9进制也就是100

9进制表示

十位数= m / 9

个位数= m % 9

将帅只有3列可移动,将帅不能位于同一列也就是共有9*(9-3)=54种组成方式

a%3 != b%3

因为下标从0开始时,各个数已经减1,输出时需要加1

m / 9 + 1

m % 9 + 1

关于循环

1 两位数最大99 所以循环可以从99开始递减

2 每个位上的数只能是从1到9组成有81种方式,则可以从81开始递减

3 合法的位置有54种,所以可以从54开始递减

4 当前a和b的位置符合条件的话,那么将a,b位置对调之后的位置也符合条件,则可以将循环从27开始

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-30 12:04:56

中国象棋将帅问题的相关文章

编程之美——中国象棋将帅问题

题目要求输出“将”(A),“帅”(B)的所有合法位置,并且只能使用一个字节存储变量: 解法一: 1 #include<iostream> 2 using namespace std; 3 4 int main() 5 { 6 int i=81; 7 while(i--) 8 { 9 if(i/9%3==i%9%3) 10 continue; 11 else 12 cout<<i/9+1<<'\t'<<i%9+1<<endl; 13 } 14 re

编程之美笔记--第一章游戏之乐--1.2中国象棋将帅问题

后来一版作者又将最后一句改为:”要求在代码中只能使用一个字节存储变量“. 我的解法: package android.zlb.java; /** * * @author zhanglibin * */ public class TestXiangqi { public static void main(String[] args) { for(int i = 11; i < 100; i++) { if(i / 10 % 3 == 1 && (i % 10 == 1 || i % 1

《编程之美》读书笔记:中国象棋将帅问题

找出将和帅所有可能的局面,要求用一个字节的变量来存储数据. 我最初分析这道题,想可以枚举将的位置,那么一共有9个,再写出帅的位置就行,由于将帅不能照面,所以此时帅只有6个位置.答案必定有9*6=54个.只是判断照面的地方会比较麻烦. 由于只有一个字节的变量限制和以前做题经验,使我一度想歪以为要用二进制的位来表示将的位置.但是这样的话,一个字节只有8位,而将可有9个位置,显然不行. 当然,不应这样做,也没有必要这样. 后来想到另一种思路,可以把将和帅的位置同时压缩到一个十进制数字N里面,这样N=a

《编程之美》之中国象棋将帅问题

一个将,一个帅,在各自的活动的9个格子里,但是两个人不能面对面,站在同一条直线上 下面两种简单的解法 #include <stdio.h> int main() { unsigned char i = 81; while (i--) { if (i / 9 % 3 == i % 9 % 3) continue; printf("a:%d,b:%d\n", i / 9, i % 9); } struct { unsigned char a:4; unsigned char b

《编程之美-读书笔记》-1 中国象棋将帅问题

时间:2014.05.27 地点:基地 ---------------------------------------------------------------------------------------- 一.指针和引用的区别 1.指针可以为空,引用不可以不空. 引用是一个对象的别用,定义一个引用时必须初始化,而声名指针时可以不指向任何对象,故使用指针时也常要做空的判断,而引用无需,因为引用总是绑定着一个对象. 2.指针可以改变指向,而引用不可以重新绑定新对象.(指针变异思迁,引用从

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

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

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

[题目] 假设在中国象棋中只剩下将帅两个棋子,国人都知道基本规则:将帅不能出九宫格,只能上下左右移动,不能斜向移动,同时将帅不能照面.问在这样条件下,所有可能将帅位置.要求在代码中只能使用一个字节存储变量. [分析] 3种方案: 1)位运算实现1个byte存入和读取2个变量. 2)使用位域把几个不同的对象用一个字节的二进制位域来表示.比如 C++ Code 12345   struct {     unsigned char a: 4;     unsigned char b: 4; } i;

第1章 游戏之乐——中国象棋将帅问题

中国象棋将帅问题 中国象棋里面双方的“将”和“帅”各自呆在自己的九宫格里,一步只能横移或纵移一格,而且双方不能见面(既不能处在同一条纵线上).在残局时有的人会用这一规则走出绝妙杀招.假设一方的“将”为A,另一方的“帅”为B,现在求双方所能出现的所有合法位置,所需变量只能用一个字节来保存. 我们用1~9的数字来,按行优先的顺序来表示每个格点的位置,如下图所示.这样只需要用模余运算就可以得到当前的列号,从而判断A.B是否互斥. [解法一]用C语言实现 一种比较正经的解法,就是用位运算,设一个char

《编程之美》中国象棋将帅问题

问题描述 中国象棋里面双方的"将"和"帅"各自呆在自己的九宫格里,一步只能横移或纵移一格,而且双方不能见面(既不能处在同一条纵线上).在残局时有的人会用这一规则走出绝妙杀招.假设一方的"将"为A,另一方的"帅"为B,现在求双方所能出现的所有合法位置,所需变量只能用一个字节来保存. 我的解法 #include <stdio.h> int main(void) { unsigned char chPos = 0x11;