根据构造方法的不同,幻方可以分成三类:奇数阶幻方、4M阶幻方和4M + 2阶幻方,其中M为自然数,2阶幻方不存在。
1 奇数阶幻方构造法
(1) 将1放在第一行中间一列;
(2) 从2开始直到n×n止各数依次按下列规则存放:按 45°方向行走,向右上,即每一个数存放的行比前一个数的行数减1,列数加1
(3) 如果行列范围超出矩阵范围,则回绕。例如1在第1行,则2应放在最下一行,列数同样加1;
(4) 如果按上面规则确定的位置上已有数,或上一个数是第1行第n列时,则把下一个数放在上一个数的下面。
2 偶数阶幻方构造
2.1 4m阶的幻方
(1) 把数1到n×n按从上至下,从左到右顺序填入矩阵
(2) 将方阵的所有4×4子方阵中的两对角线上位置的数关于方阵中心作对称交换,即a(i,j)与a(n-1-i,n-1-j)交换,所有其它位置上的数不变。
------------->
3 4m+2阶幻方
(1) 首先构造n-2=4m的幻方,然后放在n阶幻方的中心
(2) 将4m阶幻方中每个数都加上8m+2;
(3) 将1,2,...,8m+2 与 ....(4m+2)2成对排在外围的一圈,如下图,注意中心的4m阶未加上8m+2,且保证每对数相加=1+(4m+2)2
4 代码示例
4.1 奇阶幻方的生成
/** * @author: contribute to wikipedia according GNU * @description: 用於創建奇數階的幻方 */ public class magic_squre_odd { static int matrix[][]; static int n; public static void magic_squre_odd_generate() { matrix = new int[n][n]; //將所有的數初始化為0 for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) matrix[i][j] = 0; matrix[0][(n+1)/2 -1] = 1; int x = 0,y = ((n+1)/2 -1); //count: 記住已經插入過的數 for(int count = 2; count<=n*n;count++) while(true) { //先x-1 y+1 x-=1; y+=1; //判斷是否可以插入 while(true) {//循環判斷是否越界,直到一個地方不越界為止 //判斷是否越界: //越上界x<0,則移到最下方x=x+n,y不變; continue if(x<0) { x = x + n; continue; } //越右界y>=n,則y=y-n,x不變;continue if(y>=n) { y = y - n; continue; } //循環判斷是否該位置已經有數據,直到找到一個空位 //如果有數據,則移到x = x + 2;y = y - 1; continue if (y<0){y=y+n;continue;} if(matrix[x][y] != 0 ) { x = x + 2;y = y - 1; if (x>=n){x=x-n;continue;} if (y<0){y=y+n;continue;} continue; } break; } //將當前的count值賦給選出的空位 matrix[x][y]= count; break; } } public static void print() { for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { //System.out.println(matrix[i][j]); System.out.print(matrix[i][j]); System.out.print("_"); } System.out.print("/n"); } } public static void main(String[] args) { //手工輸入n的值,並確保為奇數 n = 11; magic_squre_odd_generate(); print(); } }
4.2 4m阶幻方的生成
/** * @author: contribute to wikipedia according GNU * @description: 用于创建4阶的幻方 * */ public class magic_square_4m { /** * @param args */ static int matrix[][]; static int n; static void magic_squre_4m_generate() { //初始化matrix matrix = new int[n][n]; //将matrix里的位置用数顺序排列 int ini = 0; for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) matrix[i][j] = ++ini; //打印对调前的样子 System.out.println("对调之前的样子:"); print(); //然后对调(仅对右上方的数进行遍历) for(int i = 0; i < n; i++) for(int j = i + 1; j < n; j++) { if(( i != j) && (i + j) != (n -1) ) { //对不在主付对角线上的数关于中心对调 int temp; temp = matrix[i][j]; matrix[i][j] = matrix[n -1 - i][n - 1 - j]; matrix[n -1 - i][n - 1 - j] = temp; } } } public static void print() { for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { System.out.print(matrix[i][j]); System.out.print("_"); } System.out.print("/n"); } } public static void main(String[] args) { //这里手动设置n的数值为4,这里只能设置为4,因为只求4阶幻方 n = 4; magic_squre_4m_generate(); System.out.println("对调之后的样子:"); print(); } }