看到还有人在研究幻方问题,就把十多年前的习作给大家看看----献丑了。
对任意的奇数阶幻方,设阶数为n,将1至n*n的自然数填入幻方中,使每一行、每一列、主、辅对角线元素之和相等。
一.
先说幻方生成部分的伪代码(其余验证及输出就很简单了):
1.
将k=1填入最上一行的中间位置;
2.
k从2到n*n,依次做:
2.1. 若k为n的整数倍加1,则将k填入前一个数的正下方,否则填入前一个数右上方;
2.2. 若2.1.操作的位置不在幻方范围内,则将操作位置改在同一行(或同一列)的另一端。
二.
核心代码
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int n;
/*阶数*/
int k=1;
/*自然数:1…n*n*/
int row,
col;
/*幻方的行号与列号*/
int m[25][25];
/*幻方阵列*/
scanf( "%d",
&n);
if(n % 2 == 0)
n++;
/*保证n是奇数*/
if( n>=25)
n=25;
/*太大的幻方输出有些困难,控制在25阶之内*/
printf("\n n=%d",n);
m[row=0][col=n/2] = k;
/*最上一行中间一列填入1*/
for( k=2; k<=n*n; k++)
{
if( k%n == 1)
/*k是n的整数倍加1*/
{
row=(row+1)%n;
/*填入位置是正下方,若出范围填入最上一行*/
}
else
{
row=(row-1+n)%n;
/*填入位置是右上方,若出行范围填入最下一行*/
col=(col+1)%n;
/*填入位置是右上方,若出列范围填入最左一列*/
}
m[row][col]=k;
}
for(row=0; row<n; row++)
{
printf("\n");
for(col=0; col<n; col++)
printf("%4d",m[row][col]);
}
printf("\n");
system("PAUSE");
return 0;
}
三.
游戏之作(循环体中只有一句,若无二部分铺垫,估计能看懂的人不多)
m[row=0][col=n/2]=k=1;
for(k=0; k<n*n; k++)
m[row=(k%n==1)? (row+1)%n: (row-1+n)%n][col=(k%n==1)? col:(col+1)%n]=k;