有一个n*n的矩阵(n为奇数),将1 - n^2个数填入矩阵中,每个数只能使用一次,使得填满的矩阵每一行,每一列和两条对角线上所有元素之和相等。
为完成这一工作,可以采用如下方方法构造:
为完成这一工作,可以采用如下方方法构造:
首先找到第一行中间的位置,填上1,随后在1位置的右上方填上2(越出矩阵边界回到另一端),依次类推,如果某元素的右上方已经填有数字的时候,则移位到原数字的正下方,直到把矩阵填满为止。
#include<stdio.h>
#include<malloc.h>
int main()
{
int **a;
int i, j;
int n, f;
printf("请输入一个奇数: ");
scanf("%d", &n);
a = (int **)malloc(sizeof(int *) * n);
for( i = 0; i < n; i++)
{
a[i] = (int *)malloc(sizeof(int) * n);
}
for(i =0; i < n; i++)
{
for(j = 0; j < n; j++)
{
a[i][j] = 0; // 将数组初始化为 0 , 也可以用 memset 函数
}
}
i = 0;
j = n/2;
a[i][j] = 1; // 确定1的位置
f = 2;
while(1)
{
if(f > n*n) // 结束标志
{
break;
}
i--;
j++; // 右上方
if(i < 0) // i越界
{
i = n-1;
}
if(j >= n) // j越界
{
j = 0;
}
if(a[i][j] == 0) // 判断当前位置为 0
{
a[i][j] = f;
}
else // 当前位置不为 0
{
i+=2; // 如果当前位置不为0, 则位置变到原数的下方, 而此时的位置在原数的左上方, 所以此时应该是 i+2, j--
j--;
if(i == n) // 如果i+2刚好越界, 则将i赋值为0
{
i = 0;
}
if(i == n+1) // 如果i刚好在边界, 则i+2超出边界2, 故赋值为1
{
i = 1;
}
if(j < 0)
{
j = n-1;
}
a[i][j] = f;
}
f++;
}
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
printf("%5d ", a[i][j]);
}
printf("\n");
}
free(a);
return 0;
}