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;
}