幻方,是一种古老的填数字游戏。在这个游戏中,要求将从1到n2的数值填入到n*n的方阵中,使得方阵的每行、每列以及对角线上的数值总和都相等。著名的河图洛书就是在3*3的方阵中填入1-9这9个数字,使得每行每列及对角线上数字之和为15。
对于一个n为奇数的方阵来说,我们可以按照如下的方法构造n阶幻方:
- 将1放置在第一行的中间,其后的数按照从左下方到右上方的一条对角线上依次填入,并做下列修正;
- 当到达第一行时,下一个数的放置位置是:它所处的行是最后一行,所处的列是紧跟着前一个数所处列的后面一列;(即:行数减1,再模n;列数加1,再模n。)
- 当到达最右边的一列时,下一个数的放置位置是:它所处的列是最左边的列(即第一列),它所处的行是紧跟着前一个数所处行的上一行;(即:列数加1,再模n; 行数减1,再模n。)
- 当到达一个已经填上数的方格或者已经到达幻方的右上角是,下一个数的放置位置是上一个数的方格的正下方。(即:行数加1,模n,列数不变)
请写代码构造并输出5阶幻方。
17 | 24 | 1 | 8 | 15 |
23 | 5 | 7 | 14 | 16 |
4 | 6 | 13 | 20 | 22 |
10 | 12 | 19 | 21 | 3 |
11 | 25 | 25 | 2 | 9 |
做题思路:
1)、先定义一个5*5的二维数组,并初始化每个值为0;
2)、从(0,2)即1的位置开始进入,根据题目条件改变arr[row][col]中row和col的值,使其到达下个位置,依次将1-25填入表格;
public class magic_square {
public static void main(String[] args) {
int[][] arr = new int[5][5];
//Initialize each value of the 5*5 array to 0
//建立一个5*5的二维数组,并把它的每个值初始化为0
for(int i = 0;i < arr.length;i ++){
for(int j = 0;j < arr[i].length;j ++){
arr[i][j] = 0;
}
}
//Define the initial position of 1 (0, 2)
//定义数值1的初始位置(0,2)
int row = 0,col = 2,num = 1;
while(num < 26){
//When the original value is 0, it means that the number has not been filled in
//判断当前的值是否为0,不为0时表示该位置已被填充
if(arr[row][col] == 0){
//When the first row is reached, the next position is the last row, and the number of columns increases by one
//当该位置是第一行时,下一个位置为当前行数减1,列数加1
if(row == 0 && col != 4){
arr[row][col] = num ++;
row = 4;
col ++;
}
//When the rightmost column is reached, the next position is the first case, and the number of rows is reduced by one
//当到达最右边一列时,下个位置为当前列数加1,行数减1
else if(row != 0 && col == 4){
arr[row][col] = num ++;
row --;
col = 0;
}
//When the upper right corner is reached, the next position is directly below the square of the previous number
//当到达右上角时,下一个位置为上一个位置的正下方
else if(row == 0 && col == 4){
arr[row][col] = num ++;
row ++;
}
//Otherwise, row minus one, column plus one
//当没有遇到题目中的界限,下一个位置为当前位置的右上方
else{
arr[row][col] = num ++;
row --;
col ++;
}
}
//When the original value is not 0, it means that the number has been filled in, and the position is changed.
//当该位置不为0,即已经被填充,下一个位置为上一个位置的正下方
else{
row += 2;
col --;
}
}
//print the final array
//打印最终数组
for(int i = 0;i < arr.length;i ++){
for(int j = 0;j < arr[i].length;j ++){
System.out.print(arr[i][j]+"\t");
}
System.out.println();
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)