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

        中国象棋中,将帅相隔遥远,并且不能照面,假设棋盘上只有将和帅两字,如下图所示(A表示将,B表示帅):A、B二子被限制在己方3 x 3的格子里运动,每一步,A、b分别可以横向或纵向移动一格,但不能沿对角线移动。另外,A不能面对B,也就是说,A和B不能处于同一纵向直线上,请写出一个程序,输出A、B所有合法的位置。要求代码中只能使用一个字节存储变量。


我们的常规思路是这样的:

 - - 循环A的位置

 - - - - 循环B的位置

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

 - - - - - - - - 如果满足,则输出。

// 一般的程序员会这么干:(但这里使用了2个变量)
public class ChineseChess1 {
	public static void main(String[] args) {
		for (int i = 1; i <= 9; i++) {
			for (int j = 1; j <= 9; j++) {
				if (i % 3 != j % 3){
					System.out.println("a=" + i + ",b=" + j);
				}
			}
		}
	}
}

难点:  只能使用一个字节存储变量

// 经典解法java实现:
public class ChineseChess2 {
	public static void main(String[] args) {
		int i = 81;
		while (i-- != 0) {
			if (i / 9 % 3 == i % 9 % 3)
				continue;
			System.out.println("A=" + (i / 9 + 1) + " B=" + (i % 9 + 1));
		}
	}
}

// %3 正好是上面提到的 A 和 B 格子对应的数字 mod3 判断是否相等,相等则在一条直线上( A 和 B 碰面)。

上面的解法体现了程序的简约之美,可是让我这菜鸟程序员看的稀里糊涂: i / 9 % 3 == i % 9 % 3 是什么意思呢?

我们可以通过一个测试程序得到答案:

public class ChineseChess3 {
	public static void main(String[] args) {
		int i = 81;
		while (i-- > 0) {
			System.out.print(" " + i / 9);  // 相当于双层循环的外层循环,值循环了9次再改变
		}
		int j = 81;
		System.out.println();
		while (j-- > 0) {
			System.out.print(" " + j % 9);  // 相当于双层循环的内层循环,值循环依次改变9次
		}
	}
}
输出结果:

8 8 8 8 8 8 8 8 8 7 7 7 7 7 7 7 7 7 6 6 6 6 6 6 6 6 6 5 5 5 5 5 5 5 5 5 4 4 4 4 4 4 4 4 4 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
8 7 6 5 4 3 2 1 0 8 7 6 5 4 3 2 1 0 8 7 6 5 4 3 2 1 0 8 7 6 5 4 3 2 1 0 8 7 6 5 4 3 2 1 0 8 7 6 5 4 3 2 1 0 8 7 6 5 4 3 2 1 0 8 7 6 5 4 3 2 1 0 8 7 6 5 4 3 2 1 0


通过上面的例子,同样是可以解决问题,但解法上的优劣一目了然,算法真的是一门博大精深的学问,值得我们每个程序员去细细品味!





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值