package MagicSquare; //奇数幻方的实现 public class Magic_Odd { //n 为幻方的阶数 public static int[][] magicOdd(int n) { //构造一个(n+2)*(n+2)阶的方阵 int[][] square = new int[n + 1][n + 1]; int i = 0; int j = (n + 1) / 2; //从第一行的中间那个数字(是1)开始填幻方 //n阶幻方一共有n*n个数字(从1~n*n) //奇数阶幻方的实现算法 for (int key = 1; key <= n * n; key++) { if ((key % n) == 1) i++; else { //填充当前数的右上角那个数 i--; j++; } if (i == 0) {//判断条件:若是在(n+2)*(n+2)阶方阵的第一行 if(j==n+1){ i=2; j=n; }else{ i=n; } } else{ if(j==n+1){ j=1; } } square[i][j] = key; } //对(n+2)*(n+2)阶的方阵进行筛选出中间的n*n阶幻方 int[][] matrix = new int[n][n]; for (int k = 0; k < matrix.length; k++) { for (int l = 0; l < matrix[0].length; l++) { matrix[k][l] = square[k + 1][l + 1]; } } return matrix; } //测试函数 public static void main(String[] args) { int[][] magic = Magic_Odd.magicOdd(11); //测试11阶幻方 for (int k = 0; k < magic.length; k++) { for (int l = 0; l < magic[0].length; l++) { System.out.print(magic[k][l] + " "); } System.out.println(); } } }
所谓幻方(最基本的那种),就是横,竖,对角线上的数的和等于一个常数的数字方阵
4 3 8
9 5 1
2 7 6
以上这个图,有什么规律?容易写成代码吗?我们把这个图,向右复制五次,向下复制三次,展开一下:
4 3 8 4 3 8 4 3 8 4 3 8 4 3 8
9 5 1 9 5 1 9 5 1 9 5 1 9 5 1
2 7 6 2 7 6 2 7 6 2 7 6 2 7 6
4 3 8 4 3 8 4 38 4 3 8 4 3 8
9 5 1 9 5 1 9 5 1 9 5 1 9 5 1
2 7 6 2 7 6 2 7 6 2 7 62 7 6
4 3 8 4 3 8 4 3 8 4 3 8 4 3 8
9 5 1 9 5 1 9 5 1 9 5 1 9 5 1
2 7 6 2 7 6 2 7 6 2 7 6 2 7 6
注意蓝色数字的走向。
怎么样,现在呢?现在看起来显得规律性强了很多,但是,你会不会觉得循环还是不太好写?我们如何从一个给定的n,直接得知它的坐标呢?不难,找一下规律就可以发现对于任意的数值n+1有(以左上角为0,0坐标):
x = 2 + n + n / 3;
y = 1 + n - n / 3;
其实这个规律可以简单扩展到任意奇数阶幻方(以下size是奇数):
x = size / 2 + 1 + n + n / size; (注意这里的除法是取整除法,不带小数)
y = size / 2 + n - n / size;
这样,我们就可以把原来复杂的循环,化简成一重简单循环。于是有程序: