读入数据到map,比如说map[i][j],由于是一行一行读入的,所以 i 代表行, j 代表列,而且还是从0开始的(看习惯,我喜欢从0开始),比如map[1][2]就是第2行第3列

题目要求,比如说

小雪人初始在左上角(即单元格(0, 0)),小雪人的家在右下角(即单元格(M – 1, N - 1))

那么其坐标系就是第一个数为行,第二个数为列,但是也不好说,因为后面的样例都是正方形,我怎么知道哪个是行,哪个是列。看了看24年的,里面明确说了,第一维为行,第二维为列,那么我们就按照这个标准去做。

    for (int i = 0; i < M; ++i) {      // i 是行号 (对应 y 轴)
        for (int j = 0; j < N; ++j) {  // j 是列号 (对应 x 轴)

            // --- 计算当前格子的屏幕坐标 ---
            // x = 左边距 + 列号 * 格子宽
            // y = 顶边距 + 行号 * 格子高
            int x = leftMargin + j * cellWidth;
            int y = topMargin + i * cellHeight;
        

基于此,我建议绘图部分用xy,管理部分用row和col,或者rc,方便区分


以下主要是针对模板代码里面的dfs,尤其是里面的方向数组:

这是一个非常经典且容易混淆的问题!在编程(特别是涉及矩阵、图像处理、地图网格)时,xy 的定义经常会打架。

在你的这个代码语境下(以及大多数 C++ 算法题解中):x 代表行 (Row),y 代表列 (Column)。

这与我们在数学课上学的“直角坐标系”是相反的。让我为你彻底拆解一下:

1. 为什么会混淆?

  • 数学/屏幕坐标系

    • 轴:水平向右(代表列)。
    • 轴:垂直向下(代表行)。
    • 坐标表示: 通常指 (列, 行)。
  • 数组/矩阵索引(编程习惯)

    • 二维数组定义:map[行][列]map[row][col]
    • 程序员习惯:为了对应数组写法,通常把第一个下标叫 x,第二个下标叫 y
    • 坐标表示:map[x][y] 实际上是 (第 x 行, 第 y 列)

2. 在你的代码中

看看你定义的方向数组:

// 下, 右, 上, 左
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};

我们来验证一下:

  • 向下移动:意味着行号增加,列号不变。
    • 代码里:dx = 1 (行+1),dy = 0 (列不动)。 符合“x是行”
  • 向右移动:意味着行号不变,列号增加
    • 代码里:dx = 0 (行不动),dy = 1 (列+1)。 符合“y是列”

3. 图解记忆法

请记住这个对应关系,这是算法题里的“潜规则”:

      (y轴 / 列 col)
      0   1   2   3   ...
    +---+---+---+---+
 0  |   |   |   |   |
    +---+---+---+---+
 1  |   |   |   |   |  <-- x轴 (行 row)
    +---+---+---+---+
 2  |   |   |   |   |
    +---+---+---+---+
...
  • x 控制 上下 移动(变化的是行号)。
  • y 控制 左右 移动(变化的是列号)。
  • 访问方式:grid[x][y]

4. 这里的 QPoint 是个大坑!

注意! Qt 的 QPoint 使用的是屏幕坐标系

  • QPoint(a, b) 中:
    • ax坐标 (水平/列)。
    • by坐标 (垂直/行)。

如果你在 DFS 算法里把 x 当作行,y 当作列,那么在使用 QPoint 存结果时,必须反过来写:

// 假设你的 dfs(x, y) 中,x是行,y是列
resultPath.push_back(QPoint(y, x)); 
// QPoint(水平x, 垂直y) = QPoint(列, 行)

或者,为了避免精神分裂,我建议你在 DFS 里直接改变量名,不要叫 x, y,叫 r, c

// 推荐写法:r (row), c (col)
int dr[] = {1, 0, -1, 0}; // 行变化
int dc[] = {0, 1, 0, -1}; // 列变化
 
bool dfs(int r, int c, ...) {
    // ...
    int nextR = r + dr[i];
    int nextC = c + dc[i];
    // ...
    // 存入 QPoint 时,QPoint(x, y) 对应 QPoint(列, 行)
    resultPath.push_back(QPoint(c, r)); 
}

总结: 在你的那段 dx/dy 代码里,x = 行,y = 列。如果你不改变量名,请务必记住:x 变了是上下走,y 变了是左右走