22:神奇的幻方 (从OPENJUDGE引入)
查看
描述
幻方是一个很神奇的N*N矩阵,它的每行、每列与对角线,加起来的数字和都是相同的。
我们可以通过以下方法构建一个幻方。(阶数为奇数)
1.第一个数字写在第一行的中间
2.下一个数字,都写在上一个数字的右上方:
a.如果该数字在第一行,则下一个数字写在最后一行,列数为该数字的右一列
b.如果该数字在最后一列,则下一个数字写在第一列,行数为该数字的上一行
c.如果该数字在右上角,或者该数字的右上方已有数字,则下一个数字写在该数字的下方
输入
一个数字N(N<=20)
输出
按上方法构造的2N-1 * 2N-1的幻方
样例输入
3
样例输出
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
题目分析:
幻方的构造题目已经给出,难点在于当右上角有数时的情况。判断有无数的方法就是将数组归零,元素若为“0”则无数,之后将两种情况分类讨论。
程序样例:
#include<cstdio>
int main()
{
int N,hf[41][41]={},tot=1; //tot为计数单位
scanf("%d",&N);
N=2*N-1; //构造(2N-1)*(2N-1)的幻方
int i=1,j=(N-1)/2;
while(tot<=N*N) //遍历每一个元素
{
int m,n;
m=i-1>=0? i-1:N-1;
n=j;
if(!hf[m][n]) //无数
{
hf[m][n]=tot;
i--;
j++;
}
else //有数
{
m=i+1; //降一排
if(m>=N)
m=0;
n--; //退一列
if(n<0)
n=N-1;
hf[m][n]=tot;
i++;
}
if(i<0)
i=N-1;
if(j>=N)
j=0;
tot++;
}
for(int i=0;i<N;i++)
{
if(i) //换行符格式控制
printf("\n");
for(int j=0;j<N;j++)
if(j) //空格格式控制
printf(" %d",hf[i][j]);
else
printf("%d",hf[i][j]);
}
return 0;
}