python魔方阵

问题描述

        把一串连续的正整数1~n^{2}排列成一个n行n列的二维数字矩阵(n为奇数),使矩阵的每一行、每一列以及对角线上的数字之和都等于n\times \left ( n^{2}+1 \right )\div 2。使用python代码实现上述要求,并打印出该矩阵。

        这个问题的本质就是:把1~n^{2}n^{2}个正整数,按照一定的规则排列成n行n列的矩阵。规则就是矩阵每一行的数字之和为n\times \left ( n^{2}+1 \right )\div 2,每一列的数字之和也为n\times \left ( n^{2}+1 \right )\div 2,对角线上的数字之和也为n\times \left ( n^{2}+1 \right )\div 2。需要注意的使n是一个奇数,如果n为1时,没什么研究价值,我们可以从n为3开始,看能不能找出排列的规律。

        我们可以从上面的魔方阵中发现n阶魔方阵中数字的排布规律:数字1一定位于第一行的中间列,从1开始向右上方递增1,如果超出了上边界则把超出的数字放到同一列的最后一行,如果超出了右边界则把超出的数字放到同一行的第一列,如果递增数字的位置已存在数字则向下方递增,而且需要向下方递增的数字总是n的整数倍。根据这个规律排布数字我们就能得到一个n阶魔方阵。

生成魔方矩阵

        根据魔方阵的排布规律,我们可以写出一个生成魔方阵数据的函数,代码如下:

def magic_square_array(n: int):
    """
    生成魔方矩阵
    
    :param n: 矩阵的行列数
    :return: 
    """
    if n % 2 != 1:  # 如果n不为奇数时
        raise ValueError('n must is odd number')  # 抛出n的值错误
    array = [[0] * n for i in range(n)]  # 创建一个二维列表来存放每行每列的数值
    row = 0  # 初始行的值为0
    column = n // 2  # 初始列的值为n/2,需要注意列表的索引从0开始
    for i in range(1, n ** 2 + 1):  # 使用循环连续取出1~n的平方的所有正整数
        row = n - 1 if row < 0 else row  # 如果行的值小于0时,行的值为n-1,否则行的值不变
        column = 0 if column >= n else column  # 如果列的值大于等于n时,列的值为0,否则列的值不变
        array[row][column] = i  # 把数字i存放到二维列表中
        if i % n != 0:  # 当i不能整除n时
            row -= 1  # 行的值减一
            column += 1  # 列的值加一
        else:  # 否则
            row += 1  # 行的值加一
    return array  # 返回二维列表

打印魔方矩阵

        我们再式设计一个函数来把魔方阵的数据打印出来,代码如下:

def print_array(n: int):
    """
    打印魔方矩阵

    :param n: 矩阵的行列数
    :return:
    """
    array = magic_square_array(n)  # 使用magic_square_array生成魔方矩阵二维列表
    for i in range(n):  # 使用循环连续获取行数
        for j in range(n):  # 使用循环连续获取列数
            print(str(array[i][j]).center(len(str(n**2))), end=' ')  # 打印出i行j列的数字
        print()  # 换行

完整代码

        完整代码如下:

def magic_square_array(n: int):
    """
    生成魔方矩阵

    :param n: 矩阵的行列数
    :return:
    """
    if n % 2 != 1:  # 如果n不为奇数时
        raise ValueError('n must is odd number')  # 抛出n的值错误
    array = [[0] * n for i in range(n)]  # 创建一个二维列表来存放每行每列的数值
    row = 0  # 初始行的值为0
    column = n // 2  # 初始列的值为n/2,需要注意列表的索引从0开始
    for i in range(1, n ** 2 + 1):  # 使用循环连续取出1~n的平方的所有正整数
        row = n - 1 if row < 0 else row  # 如果行的值小于0时,行的值为n-1,否则行的值不变
        column = 0 if column >= n else column  # 如果列的值大于等于n时,列的值为0,否则列的值不变
        array[row][column] = i  # 把数字i存放到二维列表中
        if i % n != 0:  # 当i不能整除n时
            row -= 1  # 行的值减一
            column += 1  # 列的值加一
        else:  # 否则
            row += 1  # 行的值加一
    return array  # 返回二维列表


def print_array(n: int):
    """
    打印魔方矩阵

    :param n: 矩阵的行列数
    :return:
    """
    array = magic_square_array(n)  # 使用magic_square_array生成魔方矩阵二维列表
    for i in range(n):  # 使用循环连续获取行数
        for j in range(n):  # 使用循环连续获取列数
            print(str(array[i][j]).center(len(str(n**2))), end=' ')  # 打印出i行j列的数字
        print()  # 换行


print_array(5)

执行结果如下:

猜你喜欢

转载自blog.csdn.net/qq_40148262/article/details/131166760