【Python】n阶魔方阵

目录

魔方阵的定义

奇数阶魔方阵

排列规律:

代码实现:

n=4k阶魔方阵

排列规律:

代码实现:

 n=4k+2阶魔方阵

排列规律:

代码实现:


 

魔方阵的定义

每行、每列以及两条对角线上的数之和均相等;由从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]

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值