#一、 思路

就是一步一步跟着走

#include <iostream>
using namespace std;

// 方向向量定义:4个方向的行/列偏移量(核心移动规则)
// p=0:右 (dx=0, dy=1) | p=1:左下 (dx=1, dy=-1)
// p=2:下 (dx=1, dy=0) | p=3:右上 (dx=-1, dy=1)
int dx[4] = { 0, 1, 1, -1 };
int dy[4] = { 1, -1, 0, 1 };

// 存储n阶蛇形矩阵,大小1001x1001可满足n≤1000的场景
int arr[1001][1001] = { 0 };

int main()
{
    int n;
    cin >> n;                // 输入矩阵阶数(n×n)
    int x = 0, y = 1;        // 初始填充位置(从(0,1)开始填2,因为(0,0)先填了1)
    int p = 1;               // 初始移动方向:p=1(左下方向)
    int i = 2;               // 当前要填充的数字(从2开始,(0,0)=1已手动初始化)
    arr[0][0] = 1;           // 矩阵左上角(0,0)填充第一个数字1

    // 循环填充:直到填满n×n个数字(i从2到n²)
    while (i <= n * n) 
    {
        arr[x][y] = i++;     // 填充当前位置,然后数字i自增(准备填下一个)

        // 核心逻辑1:分「前半段/后半段」切换方向规则
        // 前半段(i < n²/2 + n/2):右→左下、下→右上
        // 后半段(i ≥ 该值):右→右上、下→左下
        if (i < n * n / 2 + n / 2)
        {
            if (p == 0)          // 当前方向是右(p=0),切换为左下(p=1)
            {
                p = 1;
            }
            else if (p == 2)     // 当前方向是下(p=2),切换为右上(p=3)
            {
                p = 3;
            }
        }
        else                     // 后半段:切换规则改变
        {
            if (p == 0)          // 当前方向是右(p=0),切换为右上(p=3)
            {
                p = 3;
            }
            else if (p == 2)     // 当前方向是下(p=2),切换为左下(p=1)
            {
                p = 1;
            }
        }

        // 计算当前方向p的下一个坐标(nx, ny)
        int nx = x + dx[p];
        int ny = y + dy[p];

        // 核心逻辑2:边界检查与方向修正(越界时调整方向+重新计算坐标)
        if (nx < 0 || nx >= n || ny < 0 || ny >= n) 
        {
            // 按越界类型切换方向(优先级:行下界>列左界>列右界>行上界)
            if (nx >= n)          // 行越下界(nx≥n),切换为右(p=0)
            {
                p = 0;
            }
            else if (ny < 0)      // 列越左界(ny<0),切换为下(p=2)
            {
                p = 2;
            }
            else if (ny >= n)     // 列越右界(ny≥n),切换为下(p=2)
            {
                p = 2;
            }
            else if (nx < 0)      // 行越上界(nx<0),切换为右(p=0)
            {
                p = 0;
            }
            // 切换方向后,重新计算新的坐标(基于新方向p)
            nx = x + dx[p];
            ny = y + dy[p];
        }

        // 更新当前坐标为新坐标(准备下一次填充)
        x = nx;
        y = ny;
    }

    // 输出填充后的n阶矩阵
    for (int i = 0; i < n; i++) 
    {
        for (int j = 0; j < n; j++) 
        {
            cout << arr[i][j] << " "; // 输出当前位置值,空格分隔
        }
        cout << '\n';                // 每行结束换行
    }

    return 0;
}