中国象棋中,将帅相隔遥远,并且不能照面,假设棋盘上只有将和帅两字,如下图所示(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
通过上面的例子,同样是可以解决问题,但解法上的优劣一目了然,算法真的是一门博大精深的学问,值得我们每个程序员去细细品味!