一个魔方(Magic Square)是由一个1到n^2的整数构成的n*n矩阵,其中每行、每列以及两个对角线上的数字之和相等。如下面是n=5的魔方,行、列、对角线的和分别是75:
15 8 1 24 17
16 14 7 5 23
22 20 13 6 4
3 21 19 12 10
9 2 25 18 11
当n为奇数时,H.Coxeter 给出了魔方生成的简单法则:
在开始前,先搞清楚三个位置:一个是当前位置(当前已经填入数字的位置,用i, j代表行,列),一个是预计位置(估计下一个数会在哪里,用row, col代表行,列),另一个是下一个位置(下一个数的确切位置,用i, j代表行,列)。因为预计位置不一定就是下一个位置,所以这两个位置有区别的。步骤如下:
1. 先在第一行中间的位置填入1,然后再找下一个数字(此时是2)的预计位置(估计下一个数会在哪里);
2. 如果当前位置在第一行上,就让预计位置的行在最后一行(i=max),否则就在上一行(i-1);
3. 如果当前位置在第一列上,就让预计位置的列在最后一列(j=max),否则就在左一列(j-1);
4. 如果预计位置还没填入数字,下一个位置就是预计位置;
5. 如果预计的位置已填入数字,下一个位置就是当前
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 15 // 魔方行、列不超过15
int main(void)
{
static int square[MAX_SIZE][MAX_SIZE];
int i, j, row, column;
int count;
int size;
printf("Enter the size of the square: ");
scanf("%d", &size);
if(size < 1 || size > MAX_SIZE + 1) // 如果输入的值超出魔方范围
{
fprintf(stderr, "Error! Size is out of range\n");
exit(1);
}
if (!(size % 2)) // 如果输入的是偶数
{
fprintf(stderr, "Error! Size is even\n");
exit(1);
}
for (i = 0; i < size; i++)
for (j = 0; j < size; j++)
square[i][j] = 0; // 初始化输入的魔方数
square[0][(size-1) / 2] = 1; // 在第一行的中间位置放1
i = 0; // 当前位置的行
j = (size-1) / 2; // 当前位置的列
for (count = 2; count <= size * size; count++)
{
row = (i-1 < 0) ? (size-1): (i-1); // 在第一行预计位置就在最后一行,否则就在上一行
column = (j-1 < 0) ? (size-1): (j-1); // 在第一列预计位置就在最后一列,否则就在左一列
if(square[row][column]) // 预计位置已经填入数字下个位置的行就是当前的位置下面那个位置
i = (++i) % size;
else // 预计的位置未填入数字,下一个就是预计位置
{
i = row;
j = (j-1 < 0) ? (size-1): --j; // j = column
}
square[i][j] = count; // 填入数字
}
printf("Magic Square of size %d: \n", size);
for (i = 0; i < size; i++)
{
for (j = 0; j < size; j++)
printf("%5d", square[i][j]);
printf("\n");
}
printf("\n");
}
魔方问题 C语言版
最新推荐文章于 2021-11-12 13:29:39 发布