高阶幻方

    xiaoxiao2025-05-29  8

    百知教育——二维数组求高次幻方

    ​ 最近刚刚接触java,本该老老实实的码代码,奈何笔者好胜心太重,总想凸显自己的“聪明才智”,在老师指导下,开始试着用java做出幻方。初次试水,还请各位大佬多多指教。

    关于幻方

    ​ 幻方是一种将数字安排在正方形格子中,使每行、列和对角线上的数字的和都相等的方法。幻方可以分为完全幻方、乘幻方和高次幻方等。

    ​ 完全幻方指一个幻方行、列、主对角线机泛对角线各数之和均相等。

    ​ 乘幻方指一个幻方行列、对角线各数乘积相等。

    ​ 高次幻方是指,当组成幻方各数替换为2,3,……,n次幂时,仍能满足条件者,称此幻方为n次幻方。n阶幻方是由前n2(n的2次方)个自然数组成一个n阶方阵,其各行、各列及两条对角线所含的n个数的和相等。计算任意阶幻方的各行、各列、各条对角线上所有数的和的公式是:S=n*(n2+1)/2。其中,n为幻方的阶数,所求的数为S。

    编程思路

    对平面幻方的构造,分为三种情况:n为奇数,n为4的倍数,n为其他偶数(4*n+2的形式)

    奇数阶幻方

    ​ n为奇数时,最简单: (1)将1放在第一行中间一列;

    ​ (2)从2开始直到n*n止各数依次按下列规则存放:

    ​ 按45°方向行走,如右上

    ​ 每一个数存放在的行比前一个的行数减一,列数加一

    ​ (3)如果行列范围超出矩阵范围,则回绕。

    ​ 例如:1在第一行,2则放在最下一行,列数加一

    ​ (4)如果按上面的规则确定的位置上已有数字,或上一个数是第1行第n列时,则把

    ​ 下一个数放在上一个数的下面。

    偶数阶幻方

    普通偶数阶幻方

    ​ 当n为非4的倍数的偶数(即4n+2)时:首先把大方阵分解为4个奇数(2m+1)子方阵。

    ​ 按上述奇数阶幻方给4个子方阵对应赋值:

    ​ 由小到大依次为上左子阵(i),下右子阵(i+v),上右子阵(i+2v),下左子阵(i+3v)

    ​ 即4个子阵对应元素相处v,其中v=n*n/4。

    ​ 四个子矩阵由小到大排列方式为①③④②

    ​ 然后作相应的元素交换:a(i,j)与a(i+u,j)在同一列在对应交换(j<t或j>n-t+2),a(t-1,0)与a(t+u,0);a(t-1,t-1)与a(t+u-1,t-1)两对元素交换,其中u=n/2,t=(n+2)/4。

    ​ 上述交换是行列及对角线上的元素之和相等。

    4的倍数阶幻方

    ​ 采用对称元素交换法。

    ​ 首先把数1到n*n按从上到下,从左到右顺序填入矩阵;

    ​ 然后将方阵的所有4*4子方阵中的两对角线上位置的数关于方阵中心作对称交换,即a(i,j)与a(n+1-i,n+1-j)交换,所有其他位置的数不变。

    ​ 以上方法值适合于n为4或4的倍数时。

    代码内容

    奇数阶幻方

    /* (1)将1放在第一行中间一列; (2)从2开始直到n*n止各数依次按下列规则存放: 按45°方向行走,如右上 每一个数存放在的行比前一个的行数减一,列数加一 (3)如果行列范围超出矩阵范围,则回绕; 例如:1在第一行,2则放在最下一行,列数加一 (4)如果按上面的规则确定的位置上已有数字,或上一个数是第1行第n列时,则把 下一个数放在上一个数的下面。 */ import java.util.Scanner;//导包 public class OddMagicSquare { public static void main(String[] args) { Scanner sc=new Scanner(System.in); System.out.println("输入奇数阶幻方的的阶数:"); int n=sc.nextInt();//n为幻方的阶数 int[][] a=new int[n][n];//创建一个二维数组 //将1放在第一行中间一列 int line=0;//行数 int row=n/2;//列数 //将1~n*n存在num中 int num=1; while(num<n*n){ /* 把下一个数放在上一个数的下面的操作一共会有n次 */ for(int i=1;i<=n;i++){ /* 以三阶幻方为例: 第一次外层循环:内层循环的操作 1 3 2 第二次外层循环:内层循环的操作 6 5 4 第三次外层循环:内层循环的操作 8 7 9 最后的结果: 8 1 6 3 5 7 4 9 2 */ for (int j = 1; j <=n; j++) { a[line][row]=num;//1~n*n依次赋值 num++; if(j==n)continue; //内层循环n次之后,不再执行之后的代码 //每一个数存放在的行比前一个的行数减一,列数加一 line--; row++; //如果行列范围超出矩阵范围,则回绕 if (line==-1) { line=n-1; } if(row==n){ row=0; } } // 把下一个数放在上一个数的下面 line++; } } //将二维数组a遍历打印 for(int i=0;i<a.length;i++){ for(int j=0;j<a[i].length;j++){ System.out.print(a[i][j]+"\t"); } System.out.println(); } } }

    偶数阶幻方

    普通偶数阶幻方

    /* 当n为非4的倍数的偶数(即4n+2)时:首先把大方阵分解为4个奇数(2m+1)子方阵。 按上述奇数阶幻方给4个子方阵对应赋值: 由小到大依次为上左子阵(i),下右子阵(i+v),上右子阵(i+2v),下左子阵(i+3v) 即4个子阵对应元素相处v,其中v=n*n/4。 四个子矩阵由小到大排列方式为①③④② 然后作相应的元素交换:a(i,j)与a(i+u,j)在同一列在对应交换(j<t或j>n-t+2),a(t-1,0)与a(t+u,0);a(t- 1,t-1)与a(t+u-1,t-1)两对元素交换,其中u=n/2,t=(n+2)/4。 上述交换是行列及对角线上的元素之和相等。 */ package magic_square; import java.util.Scanner; public class EvenMagicSquare { public static void main(String[] args) { Scanner sc=new Scanner(System.in); int n=sc.nextInt(); int[][] a=new int[n][n]; int line=0; int row=n/4; int num=1; for(int i=1;i<=n/2;i++){ for (int j = 1; j <=n/2; j++) { //① a[line][row]=num; num++; line--; row++; if (line==-1) { line=n/2-1; } if(row==n/2){ row=0; } //② line=line+(n/2); row=row+(n/2); a[line][row]=num; num++; if(num==n*n)break; line=line-(n/2); row=row-(n/2); line--; row++; if (line==-1) { line=n/2-1; } if(row==n/2){ row=0; } //③ row=row+(n/2); a[line][row]=num; num++; row=row-(n/2); line--; row++; if (line==-1) { line=n/2-1; } if(row==n/2){ row=0; } //④ line=line+(n/2); a[line][row]=num; num++; line=line-(n/2); if(j==n/2)continue; line--; row++; if (line==-1) { line=n/2-1; } if(row==n/2){ row=0; } } line++; } for(int i=0;i<n/2;i++){ for(int j=0;j<(n-2)/4;j++){ int temp=a[i][j]; a[i][j]=a[i+n/2][j]; a[i+n/2][j]=temp; } } for(int i=0;i<n/2;i++){ for(int j=n-(n-2)/4;j<n-1;j++){ int temp=a[i][j]; a[i][j]=a[i+n/2][j]; a[i+n/2][j]=temp; } } for(int i=0;i<a.length;i++){ for(int j=0;j<a[i].length;j++){ System.out.print(a[i][j]+"\t"); } System.out.println(); } } }

    4的倍数阶幻方

    /* 采用对称元素交换法。 首先把数1到n*n按从上到下,从左到右顺序填入矩阵; 然后将方阵的所有4*4子方阵中的两对角线上位置的数关于方阵中心作对称交换,即a(i,j)与a(n+1-i,n+1-j)交换,所有其他位置的数不变。 以上方法值适合于n为4或4的倍数时。 */ import java.util.Scanner; public class Even4MagicSquare { public static void main(String[] args) { Scanner sc=new Scanner(System.in); int n=sc.nextInt(); int[][] a=new int[n][n]; int num=1; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ a[i][j]=num+j*n; } num++; } //对称元素交换法 int line=n/4; int row=n/8; for(int i=0;i<line;i++){ for(int j=0;j<=row;j++){ int temp1=a[0+i*4][0+j*4]; a[0+i*4][0+j*4]=a[n-1-(0+i*4)][n-1-(0+j*4)]; a[n-1-(0+i*4)][n-1-(0+j*4)]=temp1; int temp2=a[1+i*4][1+j*4]; a[1+i*4][1+j*4]=a[n-1-(1+i*4)][n-1-(1+j*4)]; a[n-1-(1+i*4)][n-1-(1+j*4)]=temp2; int temp3=a[2+i*4][2+j*4]; a[2+i*4][2+j*4]=a[n-1-(2+i*4)][n-1-(2+j*4)]; a[n-1-(2+i*4)][n-1-(2+j*4)]=temp3; int temp4=a[3+i*4][3+j*4]; a[3+i*4][3+j*4]=a[n-1-(3+i*4)][n-1-(3+j*4)]; a[n-1-(3+i*4)][n-1-(3+j*4)]=temp4; int temp5=a[0+i*4][3+j*4]; a[0+i*4][3+j*4]=a[n-1-(0+i*4)][n-1-(3+j*4)]; a[n-1-(0+i*4)][n-1-(3+j*4)]=temp5; int temp6=a[1+i*4][2+j*4]; a[1+i*4][2+j*4]=a[n-1-(1+i*4)][n-1-(2+j*4)]; a[n-1-(1+i*4)][n-1-(2+j*4)]=temp6; int temp7=a[2+i*4][1+j*4]; a[2+i*4][1+j*4]=a[n-1-(2+i*4)][n-1-(1+j*4)]; a[n-1-(2+i*4)][n-1-(1+j*4)]=temp7; int temp8=a[3+i*4][0+j*4]; a[3+i*4][0+j*4]=a[n-1-(3+i*4)][n-1-(0+j*4)]; a[n-1-(3+i*4)][n-1-(0+j*4)]=temp8; } } if(n/4%2!=0){ for(int i=0;i<line;i++){ int temp9=a[0+i*4][0+row*4]; a[0+i*4][0+row*4]=a[n-1-(0+i*4)][n-1-(0+row*4)]; a[n-1-(0+i*4)][n-1-(0+row*4)]=temp9; int temp10=a[1+i*4][1+row*4]; a[1+i*4][1+row*4]=a[n-1-(1+i*4)][n-1-(1+row*4)]; a[n-1-(1+i*4)][n-1-(1+row*4)]=temp10; int temp11=a[2+i*4][1+row*4]; a[2+i*4][1+row*4]=a[n-1-(2+i*4)][n-1-(1+row*4)]; a[n-1-(2+i*4)][n-1-(1+row*4)]=temp11; int temp12=a[3+i*4][0+row*4]; a[3+i*4][0+row*4]=a[n-1-(3+i*4)][n-1-(0+row*4)]; a[n-1-(3+i*4)][n-1-(0+row*4)]=temp12; } } //对称元素交换法 for(int i=0;i<a.length;i++){ for(int j=0;j<a[i].length;j++){ System.out.print(a[i][j]+"\t"); } System.out.println(); } } }

    结语

    ​ 由于笔者对幻方的所有知识都来自于百度百科,所以以上大部分文字都摘自于百度百科,但是,笔者保证文中的所有代码均出自笔者之手。

    最新回复(0)