1.2 中国象棋将帅的问题

题目: 下过中国象棋的朋友都知道,双方的“将”和“帅”相隔遥远,并且他们不能照面,在象棋残局中,许多高手能利用这一规则走出精妙的杀招,假设棋盘上只有“将”和“帅”二子(如图)(为了下面叙述方便,我们约定用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,《编程之美》书中,也有这种答案。用十进制是最先想到,也是最直观的方法。

转载于:https://my.oschina.net/markho/blog/498266

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值