百知教育——二维数组求高次幻方
最近刚刚接触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的倍数时。
代码内容
奇数阶幻方
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();
int[][] a
=new int[n
][n
];
int line
=0;
int row
=n
/2;
int num
=1;
while(num
<n
*n
){
for(int i
=1;i
<=n
;i
++){
for (int j
= 1; j
<=n
; j
++) {
a
[line
][row
]=num
;
num
++;
if(j
==n
)continue;
line
--;
row
++;
if (line
==-1) {
line
=n
-1;
}
if(row
==n
){
row
=0;
}
}
line
++;
}
}
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();
}
}
}
偶数阶幻方
普通偶数阶幻方
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的倍数阶幻方
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();
}
}
}
结语
由于笔者对幻方的所有知识都来自于百度百科,所以以上大部分文字都摘自于百度百科,但是,笔者保证文中的所有代码均出自笔者之手。