输入一个奇数n,构造并输出一个n阶等和幻方

来源:互联网 发布:国际顶级域名有哪些 编辑:程序博客网 时间:2024/04/30 07:03

输入一个奇数n,构造并输出一个n阶等和幻方,
即每一行每一列和两对角线上的n个数的和相等
如当n=9时,有:
47 58 69 80  1 12 23 34 45
57 68 79  9 11 22 33 44 46
67 78  8 10 21 32 43 54 56
77  7 18 20 31 42 53 55 66
 6 17 19 30 41 52 63 65 76
16 27 29 40 51 62 64 75  5
26 28 39 50 61 72 74  4 15
36 38 49 60 71 73  3 14 25
37 48 59 70 81  2 13 24 35


=======================


题目分析:

先搜索到奇数幻方的构造方法:

(1) 将1放在第一行中间一列;

(2) 从2开始直到n×n止各数依次按下列规则存放:
下一个数位于前一个数的右边的上方
一个数的坐标比前一个数的行数-1,列数+1
.
(3) 如果行列范围超出矩阵范围,则回绕.
即当前数位于第n列,则下一个数位于第一列(列数+1).

例如1在第1行,则2应放在最后一行(行数-1),列数同样加1;
(4) 如果按上面规则确定的位置上已有数,则把下一个数放在上一个数的下面.

 

将n*n的幻方实现为n*n的二维数组,由于n需要变动,所以使用动态二维数组.

int n是n阶幻方的边长,int i,j作为临时变量来访问数组.

 

生成好二维数组以后,代码:

 

用于填充幻方,便于接下来的位置检测.

 

接着int row, col作为当前行,当前列.int nrow, ncol作为下一数所在行,下一数所在列.

根据幻方填充规则得知,1总是位于第0行,第(n-1)/2列.

 

根据幻方规则,接下来的填充一次从2,3一直到n*n(例子中n*n=25)

所以设置一个循环,即for(i=1;i<n*n;i++),循环体为"为当前i寻找填充坐标"

 

所以,循环体为将当前行-1,当前列+1,得到的新坐标作为下一个填充目标.

如果当前行-1小于第一行,那么新坐标的行数将从倒数第一行算起,列同理.


这样将得到新的填充坐标,但是,根据幻方填充规则:如果接下来要填充的位置上已有数,则把接下来要填充的位置更改为上一个数的下面.

 

所以,接下来进入一个循环,终止条件就是找到一个目标坐标,它的值为0(因为已填充数都是不为0,如果当前目标已为0,则跳过本循环)

因为"把接下来要填充的位置更改为上一个数的下面",由于此时的目标坐标已经改为"上一个数的右边的上面",所以"上一个数的下面"对于"上一个数的右边的上面"来说就是位于它的"下面的下面的左边",即nrow+2,ncol-1.同样要判断是否到达边界.

 

最后将当前i值赋予当前目标.