上题目
- 就是横竖斜的值相加相等
规律:
-
1.第一行中间一列的值为1。所以用j=n/2+1确定1的列数,得出a[1][j]=1。
-
2.每一个数存放的行比前一个数的行数减1,列数加1。行数用i=i-1确定,列数用j=j+1确定。
-
3.如果一个数行数为第一行,则下一个数行数为最后一行。
-
4.如果一个列行数为最后一列,则下一个数列数为第一列。
-
5.如果按上面的规则确定的位置上已有数,或上一个数是第一行最后一列,则把下一个数放在上一个数的下面。
解法:
- 利用二维数组表示实现
- 将上述五点规律用代码表示
C语言实现
// 打印指定阶数的 魔方阵
#include <stdio.h>
int main()
{
int n, k , j, mo[50][50] = {0};
printf("请输入打印魔方阵的阶数:\n");
scanf("%d", &n);
// k, j 表示初始的 数字 1 位置, 下面表示循环当前元素的 位置
k = 0;
j = n/2;
// 给数字 1 填入数组中
mo[k][j] = 1;
// 1已经填进去了,我们将其他数 通过规律填到数组当中
for(int i=2; i<=n*n; i++)
{
// 条件5 的数字该这样填进去
if ((k == 0 && j == n - 1) || mo[(k-1 + n)%n][(j+1+n)%n] != 0)
{
k = k +1;
mo[k][j] = i;
}
// 2,3,4 都是一个东西, 用 k = (k-1 + n)%n; 这种 取模的运算,假如 5阶的魔法阵,5 + 1 = 1
else
{
// 下一元素行
k = (k-1 + n)%n;
// 下一元素列
j = (j+1+n)%n;
mo[k][j] = i;
}
}
// 打印魔方阵
for(i = 0; i < n; i++)
{
for(int b = 0; b< n; b++)
{
printf("%6d", mo[i][b]);
}
printf("\n");
}
return 0;
}
Python实现
- 暂时也没想到简单的实现方式,还是按照C语言的写法,写出Python语法版本的~
- 当中用到一个嵌套列表表达式, 生成 二维数组,其实也可以使用 numpy实现,array
n = int(input("请输入魔方阵的阶层:"))
# 使用嵌套列表推导式生成类似C语言的二维数组,元素均为0
mo = [[0 for i in range(n)] for i in range(n)]
k = 0
j = int(n/2)
mo[k][j] = 1
for i in range(2, n**2+1):
if (k==0 and j == n-1) or (mo[(k-1 + n)%n][(j+1+n)%n] != 0):
k += 1
mo[k][j] = i
else:
k = (k - 1 + n)%n
j = (j + 1 + n)%n
mo[k][j] = i
for i in mo:
print(i)