奇数阶幻方构造法

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;
}
posted @ 2020-08-23 22:10  Koshkaaa  阅读(780)  评论(1编辑  收藏  举报