问题描述
把一串连续的正整数1~排列成一个n行n列的二维数字矩阵(n为奇数),使矩阵的每一行、每一列以及对角线上的数字之和都等于。使用python代码实现上述要求,并打印出该矩阵。
这个问题的本质就是:把1~共个正整数,按照一定的规则排列成n行n列的矩阵。规则就是矩阵每一行的数字之和为,每一列的数字之和也为,对角线上的数字之和也为。需要注意的使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)
执行结果如下: