N为奇数时
(1) 将1放在第一行中间一列;
(2) 从2开始直到n×n止各数依次按下列规则存放:
按 45°方向行走,如向右上
每一个数存放的行比前一个数的行数减1,列数加1
(3) 如果行列范围超出矩阵范围,则回绕。
例如1在第1行,则2应放在最下一行,列数同样减1;
(4) 如果按上面规则确定的位置上已有数,或上一个数是第1行第n列时,
则把下一个数放在上一个数的下面。
这为百度百科的解释,说人话就是
1 永远在第一行的中间 ;
其余的数是 下一个数在上一个数所在行的行-1,所在列的列+1;
若行越界则为底行,若列越界则为首列;
若此位置没有数,则可正常填入,否则填入上一个数所在列的下一行的位置
#include <stdio.h>
#include <stdlib.h>
#define ROW 3
#define COS 3
void Magic(int(*arr)[COS])
{
int row = 0;
int cos = COS / 2;
arr[row][cos] = 1;
for (int i = 2; i <=ROW*COS; i++)
{
if (arr[(row - 1 + ROW) % ROW][(cos + 1) % COS] == 0)
{
row = (row - 1 + ROW) % ROW;
cos = (cos + 1) % COS;
}
else
{
row = (row + 1 + ROW) % ROW;
cos = cos;
}
arr[row][cos] = i;
}
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COS; j++)
{
printf("%-5d", arr[i][j]);
}
printf("\n");
}
printf("\n");
}
int main()
{
int arr[ROW][COS] = { 0 };
Magic(arr);
system("pause");
return 0;
}
3*3
5*5
对上述这块稍微解析一下
这个条件用于判断填入的位置是否为空
首先我们要先确定填入的位置,才能去判断
那我们怎么确定填入的位置呢?
举个例子吧,当我们要填入2时,
1 所在位置没有上一行,下一个数所填的行,为底行,那我们就不难发现只要 行变为负时,其所在行 为 底行
自然我们就能想到%取模运算符
arr[(row - 1 + ROW) % ROW]
当row-1 为负数时,其结果为ROW-1,就变为底行
当row-1 为正数时,其结果为row-1,其为上一行
这样就有效的避免了 行 下越界的问题
同理:可解决 列 右越界的问题