幻方是一种很神奇的 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 的幻方,相邻两个整数之间用单空格隔开。
输入输出样例输入 #1
3
输出 #1
8 1 6 3 5 7 4 9 2
思路:
- 1 在第一行中间位置N/2+1
- 每个数一次为前一个数右上方的一个
- 当数位N的倍数就往下走一个,直到N*N停止
如下图分析:
AC代码1对应上面思路
#includeAC代码2using namespace std; long s[10001][10001]; int n; int sum(1); //sum计数 int i, j;//i表示行,j表示列 int main() { cin >> n; i = 1, j = n / 2 + 1;//因为1是从n/2+1列开始,所以以此为j while (sum <= n * n) {//到n*n就停 s[i][j] = sum;//开始赋值 if (sum % n == 0) {//如果为n的倍数 ++i;//就往下走 if (i == n + 1)// 到头了 i = 1; } else --i, ++j;//其他点往右上方走 if (i == 0) i = n; if (j == n + 1) j = 1;//如果向右向上到了头 ++sum; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) cout << s[i][j] << " "; cout << endl; } return 0; }
思路:没必要使用很多的if语句,把幻方扩展开来,
题目的意思就是从第一行中点开始,把每一个下面的数,放到“右上角”,若右上角有数,则放到正下方。
大佬较为简单的代码
#includeusing namespace std; int n,a[40][40],x,y; int main(){ scanf("%d",&n); x=1,y=(n+1)/2; for(int i=1;i<=n*n;i++){ a[x][y]=i; if(!a[(x-2+n)%n+1][y%n+1]) x=(x-2+n)%n+1,y=y%n+1; else x=x%n+1;//数学运算 } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ printf("%d ",a[i][j]); } printf("n"); } }
0
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)