top1编程
← 返回题目
题解

【基础】蛇形填充数组

1 条题解

  • 0
    @ 2026-7-31 20:32:16

    解题思路

    把 1 到 n×n 这些数按蛇形填进 n 行 n 列的方阵。填的顺序不是一行一行,而是沿着一条条左下-右上的斜线。

    把每条斜线编号:从左上到右下依次是第 1 条、第 2 条……一共有 2n-1 条。规则是:

    • 奇数编号的斜线:从左下往右上填
    • 偶数编号的斜线:从右上往左下填

    关键规律:第 k 条斜线上的所有格子,行数 + 列数 = k + 1。比如 n=4 时,第 3 条斜线上的格子是 (3,1)、(2,2)、(1,3),行加列都等于 4。

    所以做法是:

    1. 从 k=1 循环到 2n-1,一条一条斜线处理
    2. 先算出这条斜线上格子的行范围:
      • 上半部分(k≤n):行从 k 到 1
      • 下半部分(k>n):行从 n 到 k+1-n
    3. 奇数斜线让行从大到小循环,偶数斜线让行从小到大循环
    4. 由行算出列:列 = k+1-行
    5. 把 1、2、3……依次填进去

    举例:n=4 时第 5 条斜线,行从 4 到 2,所以依次填 (4,2)、(3,3)、(2,4),正好对应方阵里 11、12、13 的位置。

    参考代码

    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    int a[15][15];  // 方阵数组,n 不超过 10
    
    int main() {
        int n;
        cin >> n;
    
        int num = 1;  // 从 1 开始依次填数字
        // 每条左下-右上的斜线编号 k,从 1 到 2n-1
        // 斜线上所有格子满足:行 + 列 = k + 1
        for (int k = 1; k <= 2 * n - 1; k++) {
            int start, end;  // 这条斜线上格子的行范围
            if (k <= n) {
                // 上半部分的斜线:行从 k 到 1
                start = k;
                end = 1;
            } else {
                // 下半部分的斜线:行从 n 到 k+1-n
                start = n;
                end = k + 1 - n;
            }
            if (k % 2 == 1) {
                // 奇数斜线:从左下往右上填,行从大到小
                for (int i = start; i >= end; i--) {
                    int j = k + 1 - i;  // 由行算出列
                    a[i][j] = num++;
                }
            } else {
                // 偶数斜线:从右上往左下填,行从小到大
                for (int i = end; i <= start; i++) {
                    int j = k + 1 - i;  // 由行算出列
                    a[i][j] = num++;
                }
            }
        }
    
        // 输出方阵,每个数字场宽为 5
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                cout << setw(5) << a[i][j];
            }
            cout << endl;
        }
        return 0;
    }
    

    复杂度分析

    • 时间复杂度:O(n²),每条斜线每个格子只填一次
    • 空间复杂度:O(n²),存整个方阵
    • 1