You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言实现N*N矩阵重力下落及空列右移功能的算法咨询

问题背景

你需要实现N*N矩阵的重力下落逻辑,包含两个核心规则:

  • 列内非空元素向下沉降,空位留在列顶部
  • 全空列由左侧非空列右移填补,最终所有非空列都靠矩阵右侧排列
    你现有实现不仅存在语法错误无法运行,逐元素移动的O(n³)逻辑性能也较差,以下是优化后的O(n²)实现方案。
实现步骤

1. 列内元素沉降处理

对每一列单独处理,仅需一次遍历即可完成所有元素下落:

  • 从每列的底部开始向上遍历,收集所有非空元素
  • 将收集到的元素从底到顶依次回填,剩余的顶部位置统一填充空值

2. 空列右移填补处理

所有列完成沉降后,处理全空列:

  • 从矩阵最右侧列开始向左遍历,收集所有非全空的列
  • 将收集到的列从右到左依次回填,剩余的左侧位置统一填充全空列
优化后代码实现
// 假设EMPTY已定义为非0~h-1范围内的值,比如#define EMPTY -1
void gravity(game_t *p) {
    int i, j, pos;
    int n = p->n;

    // 第一步:处理每一列的元素下落
    for (j = 0; j < n; j++) {
        pos = n - 1; // 指向当前列待填充的最底部空位
        // 从下往上遍历当前列,收集非空元素
        for (i = n - 1; i >= 0; i--) {
            if (p->board[i][j] != EMPTY) {
                p->board[pos][j] = p->board[i][j];
                // 避免同一个位置重复赋值的多余操作
                if (pos != i) {
                    p->board[i][j] = EMPTY;
                }
                pos--;
            }
        }
    }

    // 第二步:处理全空列,左侧非空列右移填补
    pos = n - 1; // 指向当前待填充的最右侧空列
    // 从右往左遍历所有列,收集非全空列
    for (j = n - 1; j >= 0; j--) {
        // 检查当前列是否为全空
        int is_empty_col = 1;
        for (i = 0; i < n; i++) {
            if (p->board[i][j] != EMPTY) {
                is_empty_col = 0;
                break;
            }
        }
        if (!is_empty_col) {
            // 非全空列复制到pos位置的列
            if (pos != j) {
                for (i = 0; i < n; i++) {
                    p->board[i][pos] = p->board[i][j];
                    p->board[i][j] = EMPTY;
                }
            }
            pos--;
        }
    }
}
方案说明
  • 时间复杂度为O(n²),仅需遍历矩阵常数次,远优于原逐元素移动的O(n³)实现,不需要递归即可实现最优性能
  • 逻辑分层清晰,先处理列内沉降再处理空列位移,便于后续调试和规则修改
  • 避免了重复赋值等多余操作,进一步提升运行效率

内容的提问来源于stack exchange,提问作者PhysicsStudent

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 00:09:00