幻方生成规则详解(小朋友版): 起始位置:把数字1放在第一行的正中间

移动规则(就像走格子游戏):

总是尝试往"右上方"走一步(行减1,列加1)

遇到特殊情况时调整位置:

如果走到"天花板"(第一行),就跳到"地板"(最后一行),列不变

如果走到"右墙"(最后一列),就跳到"左墙"(第一列),行不变

如果走到右上角,就直直往下走

如果右上方格子被占了,就直直往下走

数字摆放:按顺序把数字放进走到的格子里

例子(3阶幻方): text 输入:3 输出:

8 1 6

3 5 7

4 9 2

神奇之处:每行/每列/对角线之和都是15!

学习提示: 数组arry[列][行]就像围棋棋盘,第一个坐标是x(横向),第二个是y(纵向)

setw(3)让每个数字占3格空间,输出更整齐

只能生成奇数阶幻方(输入偶数会出错哦!)

#include <iostream>
#include <iomanip> // 用于setw控制输出宽度
using namespace std;

int main()
{
    int n, m;
    cin >> n; // 输入幻方阶数(奇数)
    int arry[30][30] = {0}; // 初始化30x30数组全为0(最大支持29阶幻方)

    // 计算第一行中间位置的列索引(幻方规则起始点)
    m = (n - 1) / 2; // 因为数组索引从0开始
    int tempx = m;    // 初始列位置(中间列)
    int tempy = 0;    // 初始行位置(第一行)

    arry[tempx][tempy] = 1; // 将数字1放在第一行中间列

    // 从数字2开始填充到n*n
    for (int k = 2; k <= n * n; k++)
    {
        // 情况1:当前位置在第一行但不在最后一列
        if (tempy == 0 && tempx != n - 1) {
            tempx += 1;    // 移动到最后一列
            tempy = n - 1; // 移动到最后一行
        }
        // 情况2:当前位置在最后一列但不在第一行
        else if (tempx == n - 1 && tempy != 0) {
            tempx = 0;     // 移动到第一列
            tempy -= 1;    // 移动到上一行
        }
        // 情况3:当前位置在第一行最后一列(右上角)
        else if (tempy == 0 && tempx == n - 1) {
            tempy += 1;    // 直接向下移动一行(列不变)
        }
        // 情况4:当前位置在中间区域(不在边界)
        else {
            // 尝试移动到右上方格子(行减1,列加1)
            if (arry[tempx + 1][tempy - 1] == 0) {
                tempx += 1;  // 向右移动一列
                tempy -= 1; // 向上移动一行
            }
            // 右上方已有数字则直接向下移动
            else {
                tempy += 1; // 向下移动一行(列不变)
            }
        }
        arry[tempx][tempy] = k; // 将当前数字放入新位置
    }

    // 打印幻方(按行输出)
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cout << setw(3) << arry[j][i]; // 每个数字占3个字符宽度
        }
        cout << endl; // 每行结束换行
    }
    return 0;
}

0 条评论

目前还没有评论...