目录
魔方阵的定义
每行、每列以及两条对角线上的数之和均相等;由从1到N^2的连续整数组成。
生成N阶魔方阵需考虑以下三种情况:
奇数阶魔方阵
n=4k的魔方阵
n=4k+2的魔方阵
奇数阶魔方阵
排列规律:
(1) 将1放在第一行中间一列;
(2) 从2开始直到n×n止各数依次按下列规则存放:
向右上45°行走,
每一个数存放的行比前一个数的行数-1,列数+1;
(3)如果行列范围超出矩阵范围,就回绕;(可使用余数实现回绕)
(4)如果按上面规则确定的位置上已有数,或上一个数是第一行第n列时,则把下一个数放在上一个数的正下方。
代码实现:
def magic(n):
l=[[0] * n for i in range(n)] #创建初始值为0的二维数组
if n%2==1: #n为奇数
x=0 #初始行下标
y=n//2 #初始列下标
l[x][y]=1 #从1开始填充
for i in range(2,n**2+1):
x=(x-1)%n #向右上角45°填充数字
y=(y+1)%n
if l[x][y]!=0: #位置上已有数字,放到正下方
x=(x+2)%n
y=(y-1)%n
l[x][y]=i
n=4k阶魔方阵
排列规律:
(1)将魔方阵分成k*k 个4阶魔方阵,标记4阶魔方阵的对角线(下图带颜色的方格);
(2)将 1~n^2的值按从上到下,从左到右的顺序依次填入,遇到标记的位置就先不填,将数字存入br数组;
(3)从右下角开始,从右往左,从下到上,将br数值中的值依次存入还是0的位置。
代码实现:
def magic(n):
l=[[0] * n for i in range(n)] #创建初始值为0的二维数组
elif n%4==0: #4的倍数
br=[] #存储对角线上元素
num=0
for i in range(n):
for j in range(n):
num+=1
if (i-j)%4==0 or (j-i)%4==0 or (i+j)%4==3: #取出对角线上元素
br.append(num)
else:
l[i][j]=num #从左到右、从上到下填充数字
n=4k+2阶魔方阵
排列规律:
(1)分块,把大方阵分解为4个奇数(n/2)阶子方阵,并对所分的块按照左上、右下、右上、左下的顺序进行摆放;
先生成一个n/2阶魔方阵①,①+2*x(x=n^2/4)得到右下,以此类推。
(2)对特殊位置进行标记,上下交换标记的数字:
①右半小方阵中大于k+2的列;(列下标大于k+1)
②左半小方阵中( k + 1 , k + 1 )的格位;(下标[k][k])
③左半小方阵中小于k+1的列;(列下标小于k)
(第k+1行第1列的格位不能交换,需要恢复)(下标[k][0])
代码实现:
def magic(n):
l=[[0] * n for i in range(n)] #创建初始值为0的二维数组
else: #偶数但不是4的倍数
n1=int(n/2)
l1=magic(n1) #左上的奇数魔方阵
x=int(n**2/4) #每个小魔方阵的差值
k=int((n-2)/4)
#构造大魔方阵
for i in range(n1):
for j in range(n1):
l[i][j]=l1[i][j] #左上
l[i][j+n1]=l1[i][j]+2*x #右上
l[i+n1][j]=l1[i][j]+3*x #左下
l[i+n1][j+n1]=l1[i][j]+x #右下
for i in range(n1):
for j in range(n):
#上下对调右半小方阵中下标大于k+1的列
if j>(n1+k+1):
l[i][j],l[i+n1][j]=l[i+n1][j],l[i][j]
#上下对调左半小方阵中下标小于k的列
if j<k:
l[i][j],l[i+n1][j]=l[i+n1][j],l[i][j]
#下标(k,0)格位不能交换,需要恢复
l[k][0],l[k+n1][0]=l[k+n1][0],l[k][0]
#对调左半小方阵中下标(k,k)的格位
l[k][k],l[k+n1][k]=l[k+n1][k],l[k][k]