1 条题解

  • 0
    @ 2026-6-19 10:30:06

    📝 题目大意

    给定一个 H×WH \times W 的棋盘,其中恰好有两个格子标记为 o(棋子),其余均为 -(空格)。棋子每次可向上下左右移动一格,问一枚棋子移动到另一枚棋子位置所需的最少步数。

    💡 解题思路

    1. 题目分析:棋盘上只有两个棋子,没有任何障碍物。在无障碍的网格中,从一点到另一点的最短路径就是曼哈顿距离。数据范围 H,W100H, W \le 100,直接遍历扫描即可。

    2. 算法推导

      • 遍历整个棋盘,找出两个 o 的坐标 (x1,y1)(x_1, y_1)(x2,y2)(x_2, y_2)
      • 由于没有障碍,水平方向需要走 x1x2|x_1 - x_2| 步,垂直方向需要走 y1y2|y_1 - y_2| 步。
      • 答案即曼哈顿距离:x1x2+y1y2|x_1 - x_2| + |y_1 - y_2|
    3. 边界与细节

      • 棋盘保证恰好有两个 o,无需额外判断。
      • 坐标从任意位置开始均可,因为差值取绝对值后与起始下标无关。
      • 代码中用 1-1 作为"未找到"的标记,读入第一个 o 时赋值给 (x1,y1)(x_1, y_1),第二个赋值给 (x2,y2)(x_2, y_2)

    ⏱️ 复杂度分析

    • 时间复杂度O(HW)O(HW),遍历整个棋盘一次。
    • 空间复杂度O(HW)O(HW),存储棋盘,但 H,W100H,W \le 100 实际可忽略。

    💻 标准代码 (C++)

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
        int n, m, x1 = -1, x2 = -1, y1 = -1, y2 = -1; // -1 表示未找到
        cin >> n >> m;
        char a[105][105];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                cin >> a[i][j];
                if (a[i][j] == 'o') {
                    if (x1 == -1)      // 第一个棋子
                        x1 = i, y1 = j;
                    else               // 第二个棋子
                        x2 = i, y2 = j;
                }
            }
        }
        // 曼哈顿距离 = |行差| + |列差|
        cout << abs(x1 - x2) + abs(y1 - y2);
        return 0;
    }
    
    • 1

    信息

    ID
    601
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    1
    上传者