1 条题解

  • 0
    @ 2026-8-18 11:57:16

    思路

    矩阵可以一圈一圈地"剥洋葱"。第 0 圈是最外层,第 1 圈是次外层……一共 min(n, m) / 2(向上取整)圈。

    对每一圈 L,设上下左右边界为 r1, r2, c1, c2,把这一圈边上的所有格子都填上 L:

    • 上边一整行、右边一整列先填满;
    • 下边(如果和上边不是同一行)从右往左填;
    • 左边(如果和右边不是同一列)从下往上填。

    其实这道题只用按圈填值,顺序不影响结果,按题给顺时针顺序写即可。

    代码

    #include <stdio.h>
    
    int g[105][105];
    
    int main() {
        int n, m;
        scanf("%d %d", &n, &m);
    
        int layers = ((n < m ? n : m) + 1) / 2;   // 圈数 = (min(n,m)+1)/2
    
        for (int L = 0; L < layers; L++) {
            int r1 = L, r2 = n - 1 - L;   // 该圈的上下边界
            int c1 = L, c2 = m - 1 - L;   // 该圈的左右边界
    
            for (int c = c1; c <= c2; c++) g[r1][c] = L;        // 上边
            for (int r = r1 + 1; r <= r2; r++) g[r][c2] = L;    // 右边
            if (r2 != r1)
                for (int c = c2 - 1; c >= c1; c--) g[r2][c] = L; // 下边
            if (c2 != c1)
                for (int r = r2 - 1; r > r1; r--) g[r][c1] = L; // 左边
        }
    
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++)
                printf("%d", g[i][j]);
            printf("\n");
        }
        return 0;
    }
    

    易错点

    • 圈数是 (min(n, m) + 1) / 2,例如 5×5 是 3 圈,4×6 是 2 圈。
    • 单行(如 1×100)或单列矩阵时,下边、左边的循环要跳过(用 r2 != r1、c2 != c1 判断),否则会越界或重复。
    • 输出数字之间没有空格。

    信息

    ID
    14
    时间
    1000ms
    内存
    256MiB
    难度
    2
    标签
    递交数
    1
    已通过
    1
    上传者