【问题标题】:Numbers falling down a matrix数字从矩阵上掉下来
【发布时间】:2021-12-18 23:18:42
【问题描述】:

我有一个充满元素的 N*N 矩阵。使用一个函数,我可以破坏一些元素,以便它们留下一个空白空间,可以被从上方落下的数字占据。流程示例:

[1][3][4][5]   [1][ ][4][5]   [ ][ ][ ][5]
[3][3][3][0]-->[ ][ ][ ][0]-->[ ][ ][4][0]
[3][0][2][1]-->[ ][0][2][1]-->[1][0][2][1]
[2][4][5][3]   [2][4][5][3]   [2][4][5][3]

在这个例子中,只有数字 1 和 4 掉了下来。同样,当一列完全为空时,左侧填充的那些必须向右移动。 我想创建一个函数 void Gravity (game_t * p)。

game_t 中定义:

typedef struct game{
int n; /*n*n matrix */
int h; /* numbers on matrix go from 0 to h-1*/
int ** board;  /*the actual matrix*/
} game_t

我想不出解决这个问题的好策略,你能帮帮我吗?

编辑:这是我到目前为止写的:

void gravity(game_t *p) {
  int i, j, k;
  for (k = 0; k < p->n - 1; k++) {
    for (i = p->n - 2; i = 0; i--) {
      for (j = p->n - 1; i = 0; i--) {
        if (p->board[i - 1][j] == EMPTY) {
          p->board[i - 1][j] = p->board[i][j];
          p->board[i][j] = EMPTY;
        }
      }
    }

    return;
  }

我写的这个好像效率不高,应该是递归的吧。对于从右到左的第二行到最后一行的矩阵的每个元素,我检查下面的元素是否为空并将其移动到那里。但是,我必须多次检查矩阵 (k),因为某些元素可能必须移动不止一次。 `

【问题讨论】:

  • 我知道你不会这样做,但请提供minimal reproducible example。然后,格式化您的代码,以便在每个 forwhileif 之后使用复合语句(大括号)。一致地缩进你的代码。
  • 一种下降数的算法是:对于每一列,从底部开始向上移动,标记第一个空槽,当找到第一个非空槽时停止;将其移至第一个空的。
  • 我会尝试,但我对这个问题感到困惑。至少我可以尝试正确格式化。
  • 丢弃标准是否只有 两个 相邻或 any 相邻匹配?也就是说,给定一个1 2 3 3 3 4 5,您是否希望:1 2 _ _ 3 4 5 --> _ _ 1 2 3 4 5作为第一步?还是您想要:1 2 _ _ _ 4 5 --> _ _ _ 1 2 4 5 作为第一步?
  • 别的。这 [最终] justcolumn 下降(即所有列都是独立的)吗?或者,这就像一个“选择 3”游戏,在 两个 维度上移除了一个 2D“岛”?

标签: c matrix multidimensional-array gravity


【解决方案1】:

好的,正如预期的那样:“我知道你不会这样做,但请提供一个可重现的最小示例。”人们再一次提出问题,甚至对让别人解决他们的问题不感兴趣。您提供的功能甚至无法编译...

无论如何,这里提供了一个解决方案以及测试它所需的所有代码。如果您只是在问题中使用不工作的gravity() 函数编写了所有这些内容,那将花费更少的精力。

对于未来的读者,请查看如何使用单个 malloc() 和一些强制转换完成分配,这允许通过一次调用 free() 来释放所有内容。使用指向数据的单指针而不是双指针会更好,但我知道世界各地的老师仍然喜欢双指针版本。 game_set() 函数也很有趣,因为它是一个可变参数函数

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <stdarg.h>

const int EMPTY = INT_MIN;

typedef struct game {
    int n; /*n*n matrix */
    int h; /* numbers on matrix go from 0 to h-1*/
    int **board;  /*the actual matrix*/
} game_t;

game_t *game_construct(game_t *g, int n, int h)
{
    assert(n > 0);
    g->n = n;
    g->h = h;
    g->board = malloc(n * sizeof(int*) + n * n * sizeof(int));
    g->board[0] = (int*)((char*)g->board + n * sizeof(int*));
    for (int i = 1; i < n; ++i) {
        g->board[i] = g->board[i - 1] + n;
    }
    return g;
}
game_t* game_destruct(game_t* g)
{
    free(g->board);
    return g;
}

void game_set(game_t* g, ...)
{
    va_list argptr;
    va_start(argptr, g);

    for (int r = 0; r < g->n; ++r) {
        for (int c = 0; c < g->n; ++c) {
            g->board[r][c] = va_arg(argptr, int);
        }
    }
}

void game_print(game_t *g)
{
    for (int r = 0; r < g->n; ++r) {
        for (int c = 0; c < g->n; ++c) {
            if (g->board[r][c] == EMPTY) {
                printf("[ ]");
            }
            else {
                printf("[%d]", g->board[r][c]);
            }
        }
        printf("\n");
    }
    printf("\n");
}

void gravity(game_t *g) 
{
    for (int c = 0; c < g->n; ++c) {
        int rf = g->n - 1;
        for (int r = rf; r >= 0; --r) {
            if (g->board[r][c] != EMPTY) {
                g->board[rf--][c] = g->board[r][c];
            }
        }
        while (rf >= 0) {
            g->board[rf--][c] = EMPTY;
        }
    }
}

int main(void)
{
    game_t g;
    game_construct(&g, 4, 9);
    game_set(&g,
        1, 3, 4, 5,
        3, 3, 3, 0,
        3, 0, 2, 1,
        2, 4, 5, 3);
    game_print(&g);

    game_set(&g,
        1, EMPTY, 4, 5,
        EMPTY, EMPTY, EMPTY, 0,
        EMPTY, 0, 2, 1,
        2, 4, 5, 3);
    game_print(&g);

    gravity(&g);
    game_print(&g);

    game_destruct(&g);
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多