捕获黑皇后需要的最少移动次数

2024-12-05

题目:

现有一个下标从 1 开始的 8 x 8 棋盘,上面有 3 枚棋子。

给你 6 个整数 abcdef ,其中:

  • (a, b) 表示白色车的位置。
  • (c, d) 表示白色象的位置。
  • (e, f) 表示黑皇后的位置。

假定你只能移动白色棋子,返回捕获黑皇后所需的最少移动次数。

请注意

  • 车可以向垂直或水平方向移动任意数量的格子,但不能跳过其他棋子。
  • 象可以沿对角线方向移动任意数量的格子,但不能跳过其他棋子。
  • 如果车或象能移向皇后所在的格子,则认为它们可以捕获皇后。
  • 皇后不能移动。

示例 1:

img

输入:a = 1, b = 1, c = 8, d = 8, e = 2, f = 3
输出:2
解释:将白色车先移动到 (1, 3) ,然后移动到 (2, 3) 来捕获黑皇后,共需移动 2 次。
由于起始时没有任何棋子正在攻击黑皇后,要想捕获黑皇后,移动次数不可能少于 2 次。

示例 2:

img

输入:a = 5, b = 3, c = 3, d = 4, e = 5, f = 2
输出:1
解释:可以通过以下任一方式移动 1 次捕获黑皇后:
- 将白色车移动到 (5, 2) 。
- 将白色象移动到 (5, 2) 。

提示:

  • 1 <= a, b, c, d, e, f <= 8
  • 两枚棋子不会同时出现在同一个格子上。

思路:

只要牢象不演,牢车不可能两步逮捕不了牢后,看能不能第一步直接吃到,能就1不能就2

代码:

class Solution {
public:
    bool isDiagonal(int c, int d, int e, int f) {
        int dire[4][2] = { {1, 1}, {1, -1}, {-1, 1}, {-1, -1} };
        for (int i = 0; i < 4; i++) {
            int row = c, col = d;
            while (0 < row && row < 9 && 0 < col && col < 9) {
                if (row == e && col == f) return true;
                row += dire[i][0];
                col += dire[i][1];
            }
        }
        return false;
    }
    int minMovesToCaptureTheQueen(int a, int b, int c, int d, int e, int f) {
        // 不是1,就是2。因为车包是可以两步到达任意一个地点的。
        // 判断能不能一次捕获皇后
        // 车 和 后 在同一行/列,同时 象 不在它们中间就是 1
        // 象 和 后 在同一对角线,同时 车 不在它们中间就是 1
        if (a == e) {
            if (a != c) return 1;
            else if (d < min(b, f) || d > max(b, f)) return 1;
        }
        if (b == f) {
            if (b != d) return 1;
            else if (c < min(a, e) || c > max(a, e)) return 1;
        }
        // 同一对角线判定
        if (isDiagonal(c, d, e, f)) {
            int difRow = e - c > 0 ? 1 : -1, difCol = f - d > 0 ? 1 : -1;
            while (c != e && d != f) {
                if (c == a && d == b) return 2;
                c += difRow;
                d += difCol;
            }
            return 1;
        }
        return 2;
    }
};