题目描述
幻方是一种很神奇的 N∗N 矩阵:它由数字 1,2,3,⋯⋯,N×N 构成,且每行、每列及两条对角线上的数字之和都相同。
当 N 为奇数时,我们可以通过下方法构建一个幻方:
首先将 1 写在第一行的中间。
之后,按如下方式从小到大依次填写每个数 K(K=2,3,⋯,N×N) :
- 若 (K-1)在第一行但不在最后一列,则将 K 填在最后一行,(K−1) 所在列的右一列;
- 若 (K-1) 在最后一列但不在第一行,则将 K 填在第一列,(K−1) 所在行的上一行;
- 若 (K-1) 在第一行最后一列,则将 K 填在 (K−1) 的正下方;
- 若 (K-1) 既不在第一行,也不在最后一列,如果 (K−1) 的右上方还未填数,则将 K 填在 (K−1) 的右上方,否则将 K 填在 (K−1) 的正下方。
现给定 N ,请按上述方法构造 N×N 的幻方。
输入格式
一个正整数 N ,即幻方的大小。
输出格式
共 N 行 ,每行 N 个整数,即按上述方法构造出的 N×N 的幻方,相邻两个整数之间用单空格隔开。
输入输出样例
输入
3输出
8 1 6 3 5 7 4 9 2
方法一:暴力模拟,按照题目要求判断,代码及注释如下:
#include<stdio.h>
int matrix[40][40]; //定义一个全局二维数组,数组中每个元素初始化为0
int main()
{
int n = 0;
scanf("%d",&n); //输入数字n
int x = 0,y = n / 2; //x、y分别表示k所处的位置
matrix[x][y] = 1; //k=1时 1默认在第一行中间 本题不考虑输入偶数的情况
for(int k = 2;k <= n * n;k++) //从k=2开始,按照题目要求判断
{
if(x == 0 && y != n-1) //第一种情况
{
x = n - 1;
y += 1;
}
else if(x != 0 && y == n-1) //第二种情况
{
x -= 1;
y = 0;
}
else if(x == 0 && y == n-1) //第三种情况
{
x += 1;
}
else if(x != 0 && y != n-1) //第四种情况
{
if(matrix[x-1][y+1] == 0) //如果此时右上角没数,则填在右上角
{
x -= 1;
y += 1;
}
else //若右上角有数,则填在正下方
{
x += 1;
}
}
matrix[x][y] = k; //判断完毕后将k放到x、y的位置上
}
for(int i = 0;i < n;i++) //将幻方打印输出
{
for(int j = 0;j < n;j++)
{
printf("%d ",matrix[i][j]);
}
printf("\n");
}
return 0;
}
方法二(看了一些题解后发现):
幻方规律:从第一行中间放置1后,后一个数字都是放在前一个数字的右上方,若那个位置已经有数字,则放在这个数字的正下方(注意是否越界,第一行数字的右上方在最后一行,最后一列数字的右上方在第一列)
下面是代码及注释:
#include<stdio.h>
int matrix[40][40]; //定义一个全局二维数组,数组中每个元素初始化为0
int main()
{
int n = 0;
scanf("%d",&n); //输入数字n
int x = 0,y = n / 2; //x、y分别表示k所处的位置
matrix[x][y] = 1; //k=1时 1默认在第一行中间 本题不考虑输入偶数的情况
for(int k = 2;k <= n * n;k++) //从k=2开始遍历到n*n结束
{
int xx = x,yy = y; //记录当前位置下标,方便右上角有数时返回上一步定位正下方的操作
x--;
if(x < 0) x = n-1;
//若行越界(当前数字位于第一行,注意我们所说的矩阵中的第一行为二维数组中的第0行),
//则应置于最后一行
y++;
if(y > (n-1)) y = 0;
//若列越界(当前数字位于最后一列,注意我们所说的最后一列为二维数组中的第n-1列,
//因为有第0列),则应置于第一列
//以上x++ 和 y-- 两行语句完成了往右上角移动的操作
if(matrix[x][y] != 0)
//如果右上角有数字(因为此时x、y已经进行了向右上角移动的操作,
//所以需要通过xx、yy来定位当前数字的正下方)
{
x = xx + 1;
y = yy;
}
matrix[x][y] = k; //将k放到判断好后的位置
}
for(int i = 0;i < n;i++) //将幻方打印输出
{
for(int j = 0;j < n;j++)
{
printf("%d ",matrix[i][j]);
}
printf("\n");
}
return 0;
}