Siamese方法(Kraitchik 1942年,pp. 148-149)是构造奇数阶幻方的一种方法,说明如下:
- 把\(1\)放置在第一行的中间。
- 顺序将\(2,3,......\)等数放在右上方格中。
- 当右上方格出界的时候,则由另一边进入。
- 当右上方格中已经填有数,则把数填入正下方的方格中。
- 按照以上步骤直到填写完所有\(N^2\)个方格。
(由于幻方的对称性,也可以把右上改为右下、左上以及左下等方位)
代码实现:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int N;
while (cin >> N && N)
{
//构建二维数组
vector<vector<int>> a(N, std::vector<int>(N, 0));
//幻方和 N(N*N+1)/2
int i = 0, j = N / 2;//确定第一个位置放入1
int m, v; //用m和v来记录本次填入的位置给下次使用
for (int t = 1; t <= N * N; ++t)
{
if (a[i][j] == 0)
{
a[i][j] = t;
m = i;
v = j;
}
else
{
i = m + 1;
j = v;
a[i][j] = t;
}
if (i == 0)
i = N-1;//若已经是第一行,则下个数字存放在最后一行
else
i--;
if (j == N - 1)
j = 0;
else
j++;
}
//输出的时候倒序输出
for (int p = N - 1; p >= 0; p--)
{
for (int q = 0; q < N; q++)
{
//保持数位相同,3以内的n平方最大的数字是9,3-9,n平方最大时81二位数,11-29.n方最大三位数
if(N<=3)
printf("%d ", a[p][q]);
else if (N <= 9)
printf("%2d ", a[p][q]);
else
printf("%3d ", a[p][q]);
}
cout << endl;
}
cout << endl;
}
return 0;
}