文档章节

1.2 中国象棋将帅的问题

奋斗到天明
 奋斗到天明
发布于 2015/08/27 17:55
字数 926
阅读 67
收藏 0

题目: 下过中国象棋的朋友都知道,双方的“将”和“帅”相隔遥远,并且他们不能照面,在象棋残局中,许多高手能利用这一规则走出精妙的杀招,假设棋盘上只有“将”和“帅”二子(如图)(为了下面叙述方便,我们约定用A表示“将”,B表示“帅”): 

 1 

A、B二子被限制在己方的3x3的格子里运动,例如,在如上表格里,A被正方形{d10,f10,d8,f8}包围,而B被正方形{d3,f3,d1,f1}包围。每一步,A、B分别可以横向或者纵向移动一格,但是不能沿对角线移动,另外,A不能面对B,也就是说,A和B不能处在一纵向直线上(比如A在d(10)的位置上,那么B就不能在d1、d2以及d3)。 

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

我的理解:下过象棋的都知道,将帅只能在“宫”中,而且不能碰面。这个题目就是要算出将帅有多少种合法的摆法。

当然,这肯定得用到循环。所以第一步,将棋盘坐标有序化,将其可能的位置用数字代表:

  2 

这样就可以用两层循环+判断解决问题了,但是有个限制,只能程序中使用一个变量!Java中的for循环果断不能用啊!但是单用while也不好实现。 这里我考虑将第一层循环与第二层循环合并,这样就绕过这个问题咯。用一个两位数的十位与个位分别表示A与B,那么合并的循环就可以取99:上代码:

public static void section1(){
    int i = 99;
    while(i>10){
        if(i%10!=0){
            if((i/10 - 1)/3 != (i%10 - 1)/3){
                System.out.println( "a:" + (i/10)  + ",b:" + (i%10));
            }
        }
        i--;
    }
}

考虑好看,可以添加两个常量,表示位置,如下:

public static void  section2(){
    final String[] a = {"d10","d9","d8","e10","e9","e8","f10","f9","f8"};
    final String[] b = {"d3","d2","d1","e3","e2","e1","f3","f2","f1"};
    int i = 99;
    while(i>10){
        if(i%10!=0){
            if((i/10 - 1)/3 != (i%10 - 1)/3){
                System.out.println( "a:" + a[(i/10) -1] + ",b:" + b[(i%10) -1]);
            }
        }
        i--;
    }
}

当然也可以利用强制类型转换,直接在输出的字母,如下:

public static void  section3(){
    int i = 99;
    while(i>10){
        if(i%10!=0){
            if((i/10 - 1)/3 != (i%10 - 1)/3){
                System.out.println( "将:" + (char)((i/10 -1)/3 + 100) + ((i/10 -1)%3 + 8)  + ",帅:" + (char)((i%10 -1)/3 + 100) + ((i%10 -1)%3 + 1));
            }
        }
        i--;
    }
}

最终结果:

将:f10,帅:e3
将:f10,帅:e2
将:f10,帅:e1
将:f10,帅:d3
将:f10,帅:d2
将:f10,帅:d1
将:f9,帅:e3
将:f9,帅:e2
将:f9,帅:e1
将:f9,帅:d3
将:f9,帅:d2
将:f9,帅:d1
将:f8,帅:e3
将:f8,帅:e2
将:f8,帅:e1
将:f8,帅:d3
将:f8,帅:d2
将:f8,帅:d1
将:e10,帅:f3
将:e10,帅:f2
将:e10,帅:f1
将:e10,帅:d3
将:e10,帅:d2
将:e10,帅:d1
将:e9,帅:f3
将:e9,帅:f2
将:e9,帅:f1
将:e9,帅:d3
将:e9,帅:d2
将:e9,帅:d1
将:e8,帅:f3
将:e8,帅:f2
将:e8,帅:f1
将:e8,帅:d3
将:e8,帅:d2
将:e8,帅:d1
将:d10,帅:f3
将:d10,帅:f2
将:d10,帅:f1
将:d10,帅:e3
将:d10,帅:e2
将:d10,帅:e1
将:d9,帅:f3
将:d9,帅:f2
将:d9,帅:f1
将:d9,帅:e3
将:d9,帅:e2
将:d9,帅:e1
将:d8,帅:f3
将:d8,帅:f2
将:d8,帅:f1
将:d8,帅:e3
将:d8,帅:e2
将:d8,帅:e1

改进的地方:可以利用九进制减少循环的次数,改循环数为81,用除九的商表示A,除九的模表示B,《编程之美》书中,也有这种答案。用十进制是最先想到,也是最直观的方法。

© 著作权归作者所有

共有 人打赏支持
上一篇: 次数统计-CountMap
下一篇: 杂记
奋斗到天明
粉丝 18
博文 112
码字总数 82707
作品 0
昌平
程序员
私信 提问
Silverlight+WCF 新手实例 象棋 主界面-状态重置(三十四)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 正如我们在:Silverlight+WCF 新手实例 象棋 主界面-事件区-求和认输(三十二)里面提到的一样: “游戏结束了,要干点什么呢?当然就是...

晨曦之光
2012/03/09
0
0
中国象棋棋盘游戏开发库--libcnchess

libcnchess 是一个用于开发基于两个玩家的中国象棋棋盘游戏的库, 它的目标是提供灵活方便的功能让用户可以 不需要熟悉太多象棋规则即可开发出自己的象棋游戏 特性 提供解释符合中国象棋协会标...

红薯
2014/08/08
708
0
用VC6.0编得中国象棋无法运行

@红薯 你好,想跟你请教个问题:用VC6.0编得中国象棋无法运行,代码我已上传;如果你有时间你把具体实现的步骤告诉我行吗?谢谢了!

黑狼9
2012/11/07
112
2
中国象棋--GMChess

GMChess 是一款 Linux 下的中国象棋软件。 正值svn版本号100,发布GMChess的第一个版本0.10吧。目前只有读谱功能,支持qq象棋,联众象棋,中游象棋,象棋演播室等软件生成的棋谱。 使用方法:...

匿名
2009/03/26
10.5K
1
围棋界打败人类无敌手的AlphaGo咋就不来下下中国象棋?

  横空出世,横扫围棋界所有世界冠军,去年吊打韩国棋手李世石、今年元旦车轮战人类顶尖棋手,5月虐哭中国棋手柯洁的机器人AlphaGo,这两天又火了!         因为昨儿,AlphaGo的开发...

有趣的人工智能
2017/10/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

最重要的是做什么,而不是怎么做。

最重要的是做什么,而不是怎么做。 做什么是战略,怎么做是战术。将军下令说,天黑前拿下这座山头,这是战略。手下的士兵可以不知道为什么要拿下这座山头,还非得是天黑之前,但士兵必须知道...

我是菜鸟我骄傲
32分钟前
0
0
w, vmstat, top, sar, nload命令查看系统状态信息

w/uptime 查看系统负载 cat /proc/cpuinfo 查看cpu核数 vmstat 监控系统状态,用法 vmstat 1,关键的几列: r, b, swpd, si, so, bi, bo, us, wa top 查看进程使用资源情况 top -c 显示详细的...

野雪球
今天
2
0
小白创建一个spring boot项目

进入 https://start.spring.io/

lilugirl
今天
3
0
Alibaba Java诊断利器Arthas实践--使用redefine排查应用奇怪的日志来源

背景 随着应用越来越复杂,依赖越来越多,日志系统越来越混乱,有时会出现一些奇怪的日志,比如: [] [] [] No credential found 那么怎样排查这些奇怪的日志从哪里打印出来的呢?因为搞不清...

hengyunabc
今天
2
0
home hosts

home hosts lwk@qwfys:~$ cat /etc/hosts127.0.0.1 localhost127.0.1.1 qwfys192.168.56.101vm600.qwfys.com39.108.212.91alpha1.ppy.com39.108.117.122alpha2.p......

qwfys
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部