2 条题解

  • 0
    @ 2026-3-9 22:00:22

    魔法矩阵旋转函数讲解

    我来给你逐行、逐公式讲清楚这个旋转函数 xuanzhzuan 为什么这么写,以及里面的坐标公式是怎么推导出来的。

    一、先看懂题目要求

    1. 矩阵是1-based(行、列从 1 开始数)
    2. 每次旋转:以 (x,y) 为中心,边长 2r+1 的正方形
    3. z=0 顺时针转 90°,z=1 逆时针转 90°
    4. 必须用临时数组 b 暂存结果,不能直接在原数组 a 上改,否则会覆盖还没用到的数据

    二、函数整体结构

    void xuanzhzuan (int x,int y,int r,int z) {
        // 第一步:把旋转后的值存到 b 里
        for (int i = x-r; i <= x+r; i++) {
            for (int j=y-r;j<=y+r;j++) {
                if (z==0) b[i][j] = a[x+y-j][y-x+i];  // 顺时针
                else      b[i][j] = a[x-y+j][x+y-i];  // 逆时针
            }
        }
        // 第二步:把 b 复制回 a
        for (int i = x-r; i <= x+r; i++) {
            for (int j=y-r;j<=y+r;j++) {
               a[i][j] = b[i][j];
            }
        }
    }
    

    作用

    • 遍历要旋转的小正方形里每一个位置 (i,j)
    • 计算这个位置旋转后应该从原数组的哪个位置拿数
    • 先存到临时数组 b,最后统一覆盖回 a

    三、核心:坐标变换公式(最关键)

    我们先定义:

    • 中心坐标:(cx, cy) = (x, y)
    • 当前要填的位置:(i, j)
    • 我们要找:旋转后 (i,j) 应该等于原来的哪个位置 (u, v)

    1. 顺时针旋转 90° 公式

    b[i][j] = a[ x + y - j ][ y - x + i ];
    

    等价于:

    u = x + y - j
    v = y - x + i
    

    推导原理(以中心为原点)

    1. 相对中心的坐标: dx = i - x(行偏移) dy = j - y(列偏移)

    2. 顺时针 90° 旋转的数学变换: 新dx = dy 新dy = -dx

    3. 还原回原数组坐标: u = x + 新dx = x + dy = x + (j - y) v = y + 新dy = y - dx = y - (i - x)

    4. 整理后就是代码里的公式:

      u = x + y - j
      v = y - x + i
      

    2. 逆时针旋转 90° 公式

    b[i][j] = a[ x - y + j ][ x + y - i ];
    

    等价于:

    u = x - y + j
    v = x + y - i
    

    推导原理

    1. 相对中心:dx = i-x,dy = j-y
    2. 逆时针 90° 数学变换: 新dx = -dy 新dy = dx
    3. 还原后整理,就得到上面的公式。

    四、为什么要用两个循环 + 临时数组 b?

    第一个循环:只读取原数组 a,计算旋转后的值,写入 b 第二个循环:把 b 完整复制回 a

    如果不使用 b、直接修改 a:

    • 你会把还没用到的原始值覆盖掉
    • 后面的位置计算就会用错数据
    • 结果直接乱掉

    所以必须用临时数组,这是矩阵旋转的标准写法。


    五、循环范围为什么是 i=x-r ~ x+r?

    • 中心是 x 行,半径 r
    • 向上延伸 r 行:x - r
    • 向下延伸 r 行:x + r
    • 列同理:y - ry + r
    • 刚好形成 2r+1 阶正方形,完全符合题目要求

    六、一句话总结这个函数

    遍历以 (x,y) 为中心、半径 r 的正方形内每一个点 (i,j), 根据顺时针/逆时针的数学坐标变换公式,找到它在原数组中对应的位置, 用临时数组暂存结果,最后覆盖回原数组,完成旋转。


    总结

    1. 公式来源:矩阵旋转的相对坐标数学变换,不是瞎写的
    2. 临时数组 b:防止覆盖原始数据,保证旋转正确
    3. 循环范围:刚好圈出要旋转的 2r+1 阶小方阵
    4. 两行公式:分别对应顺时针、逆时针 90° 旋转

    你现在的代码完全正确,可以直接 AC 这道题!

    信息

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