高阶幻方
百知教育——二維數組求高次幻方
? 最近剛剛接觸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++){/*以三階幻方為例:第一次外層循環:內層循環的操作132第二次外層循環:內層循環的操作654第三次外層循環:內層循環的操作879最后的結果:8 1 63 5 74 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();}}}結語
? 由于筆者對幻方的所有知識都來自于百度百科,所以以上大部分文字都摘自于百度百科,但是,筆者保證文中的所有代碼均出自筆者之手。
總結
- 上一篇: 【Python】基础速通
- 下一篇: 浅析:S2B2C模式