奇数魔方阵 n×n(n>=3)如果n=3,则有n*n个数。(即从1开始到n×n)令其横竖斜相加均相等
-
奇数阶幻方最经典的填法是罗伯特法(也有人称之为楼梯方)。填写方法是这样:
1> 每一个数放在前一个数的右上一格
2> 如果这个数所要放的格已经超出了顶行那么就把它放在底行,仍然要放在右一列
3> 如果这个数所要放的格已经超出了最右列那么就把它放在最左列,仍然要放在上一行
4> 如果这个数所要放的格已经超出了顶行且超出了最右列,那么就把它放在前一个数的下一行同一列的格内
5> 如果这个数所要放的格已经有数填入,处理方法同(4)。 -
思路:(我们令行数为::prevRow 列数为:prevCol)
1> 首先要往中间放置数字,我们就往第一行的中间放置1,然后在它的上一行下一列放置2,再在2的上一行下一列放置3,依次到9。因为数组是有界的,所以我们要将它想象成一个卷纸形状,上下左右均可形成卷纸。
2> 我们发现在放置过程中该数的上一行下一列可能已有数据,此时我们就应该将此数放置在上一个数字的下一行。
3> 我们可以发现行数减一以及列数加一之后会发生数组越界,此处有一个简单的语句替换:即 (prevRow-1+row)% row ; (prevCol+1)% row。
过程如下:
public class SuDoKu {
public static void magicSqure(int[][] array,int row) {
if(row % 2 == 0) {
return;
}
array[0][row/2] = 1;
int prevRow = 0;
int prevCol = row/2;
for (int i = 2; i <= row*row; i++) {
if(array[(prevRow-1+row)%row][(prevCol+1)%row] != 0) {
prevRow = (prevRow+1)%row;
} else {
prevRow = (prevRow-1+row)%row;
prevCol = (prevCol+1)%row;
}
array[prevRow][prevCol] = i;
}
}
public static void main(String[] args) {
int[][] array = new int[3][3];
magicSqure(array,3);
System.out.println(Arrays.deepToString(array));
}
}
运行结果:
打印n阶奇数魔方阵:
public class TestSuDoKu {
public static void SuDoKu(int [][]brray, int row) {
if (row % 2 == 0) {
return;
}
int prevRow = 0;//行数
int prevCol = row / 2;//列数
brray[prevRow][prevCol] = 1;
for (int i = 2; i <= row * row; i++) {
if (brray[(prevRow - 1 + row) % row][(prevCol + 1) % row] != 0) {
prevRow = ( prevRow + 1 ) % row;
}else {
prevRow = (prevRow - 1 + row) % row;
prevCol = (prevCol + 1) % row;
}
brray[prevRow][prevCol] = i;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入阶数:");
int row = scanner.nextInt();
int [][] brray = new int[row][row];
SuDoKu(brray,row);
System.out.println(Arrays.deepToString(brray));
}
}