每一行、每一列、每一对角线上的元素之和相等的矩阵叫魔方矩阵;只适合奇数。
规则:
- 将数字1放到,第一行的中间位置
- 新来的数字,放到当前数字的:上一行,下一列
- 如果上一行下一列,有数字。把要放入的数字,放到当前数字的下一行
方法1:
/**
* 魔方矩阵
* @param n
* @return
*/
public static int[][] RubiksCube(int n) {
if(n < 0 || n % 2 == 0) {
return null;
}
int[][] array = new int[n][n];
int i = 0,j = 0,m = 2; //i 行; j 列; m 数字;
j = n/2; //mid 中间位置
array[0][j] = 1; //将数字1放到,第一行的中间位置
int temp_i = 0,temp_j = 0; //储存i、j的临时量
for(;m <= n*n;m++) {
temp_i = i;
temp_j = j;
i--;
j++;
i = judge(i,j,n)[0];
j = judge(i,j,n)[1];
if(array[i][j] != 0) {
i = temp_i+1;
i = judge(i,j,n)[0];
j = temp_j; //temp_i、temp_j 保存的是以前的i、j 所以不用判断调整,肯定合法
}
array[i][j] = m;
}
return array;
}
/**
* 判断并调整i、j的位置
* @param i
* @param j
* @param n
* @return
*/
public static int[] judge(int i,int j,int n) {
if(i < 0) {
i = n-1; //i代表行数
}
if(j >= n) {
j = 0;
}
return new int[] {i,j};
}
public static void main(String[] args) {
int x = 5; //当输入数字5时
for(int i = 0;i < RubiksCube(x).length;i++) {
System.out.print(Arrays.toString(RubiksCube(x)[i]));
System.out.println();
}
[17, 24, 1, 8, 15]
[23, 5, 7, 14, 16]
[4, 6, 13, 20, 22]
[10, 12, 19, 21, 3]
[11, 18, 25, 2, 9]
方法2:
public static void magicScqure(int[][] array,int n) {
array[0][n/2] = 1;
int prevRow = 0;
int prevCol = n/2;
for(int i = 2;i <= n*n;i++) {
if(array[(prevRow-1+n)%n][(prevCol+1)%n] != 0) {
//上一行的下一列没有数据
prevRow = (prevRow+1)%n;//下一行
} else {
prevRow = (prevRow-1+n)%n;
prevCol = (prevCol+1)%n;
}
array[prevRow][prevCol] = i;
}
}