本题思路:用一个二维数组ms模拟幻方,先将数字1插入幻方,并用dx、dy记录此时的位置(即记录k-1的横纵坐标),然后按照题中要求插入数据并及时更新dx、dy

#include <iostream>
using namespace std;

int magic_square[45][45];

int main(void)
{
    int N;
    scanf("%d", &N);
    int count = N * N;
    
    //存放1
    magic_square[1][(N+1)/2] = 1;
    
    //用dx dy来表示k-1的坐标
    int dx = 1;
    int dy = (N+1) / 2;
    
    for(int k = 2; k <= count; k++)
    {
        //若 (K-1) 在第一行但不在最后一列,则将 K 填在最后一行, (K-1) 所在列的右一列
        if(1 == dx && dy != N)
        {
            magic_square[N][dy+1] = k;
            dx = N;
            dy = dy + 1;
        }
        else if(N == dy && dx != 1) //若 (K-1) 在最后一列但不在第一行,则将 K 填在第一列, (K-1) 所在行的上一行;
        {
            magic_square[dx-1][1] = k;
            dx = dx - 1;
            dy = 1;
        }
        else if(1 == dx && N == dy) //若 (K-1) 在第一行最后一列,则将 K 填在 (K-1) 的正下方
        {
            magic_square[dx+1][dy] = k;
            dx = dx + 1;
        }
        else if(dx != 1 && dy != N) //若 (K-1) 既不在第一行,也不在最后一列
        {
            //如果 (K-1) 的右上方还未填数,则将 K 填在 (K-1) 的右上方,否则将 L 填在 (K-1) 的正下方
            if(0 == magic_square[dx-1][dy+1])
            {
                magic_square[dx-1][dy+1] = k;
                dx = dx - 1;
                dy = dy + 1;
            }
            else
            {
                magic_square[dx+1][dy] = k;
                dx = dx + 1;
            }
        }
    }
    
    //打印数据
    for(int i = 1; i <= N; i++)
    {
        for(int j = 1; j <= N; j++)
            printf("%d ", magic_square[i][j]);
        printf("\n");
    }
    return 0;
}