幻方是一个很神奇的 N×N 矩阵,它的每行、每列与对角线,加起来的数字和都是相同的。我们可以通过以下方法构建一个幻方。(阶数为奇数)
第一个数字写在第一行的中间
下一个数字,都写在上一个数字的右上方:
如果该数字在第一行,则下一个数字写在最后一行,列数为该数字的右一列
如果该数字在最后一列,则下一个数字写在第一列,行数为该数字的上一行
如果该数字在右上角,或者该数字的右上方已有数字,则下一个数字写在该数字的下方
输入格式
一个数字 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
解题思路:
#include<iostream>
#include<cstring>
using namespace std;
int n,cnt;
int mp[200][200];
int main(){
cin >> n;
int x,y,nx,ny;
x = 0;
y = (2 * n - 1) / 2;//列数 2
mp[x][y] = ++cnt;//1
while(true){
if(cnt == (2 * n - 1) * (2 * n - 1))break;
int ny = (y + 1) % (2 * n - 1); //3 % 5 =3
if(x == 0){
nx = 2 * n - 2; // 4
}else{
nx = x - 1;
}
if( x == 0 && y == 2 * n - 2){
nx = 1;
ny = 2 * n - 2;//4
mp[nx][ny] = ++cnt;
}else if(mp[nx][ny]){
nx = (x + 1) % (2 * n - 1);//5
ny = y;//2
mp[nx][ny] = ++cnt;
}else{
mp[nx][ny] = ++cnt;
}
x = nx;//4
y = ny;//3
}
for(int i = 0;i < (2 * n - 1);i++){
for(int j = 0;j < (2 * n - 1);j++){
if(j == 0){
cout << mp[i][j];
} else{
cout << " " << mp[i][j];
}
}
cout << endl;
}
return 0;
}