【LeetCode-999】可以被一步捕获的棋子数

问题

在一个 8 x 8 的棋盘上,有一个白色车(rook)。也可能有空方块,白色的象(bishop)和黑色的卒(pawn)。它们分别以字符 “R”,“.”,“B” 和 “p” 给出。大写字符表示白棋,小写字符表示黑棋。

车按国际象棋中的规则移动:它选择四个基本方向中的一个(北,东,西和南),然后朝那个方向移动,直到它选择停止、到达棋盘的边缘或移动到同一方格来捕获该方格上颜色相反的卒。另外,车不能与其他友方(白色)象进入同一个方格。

返回车能够在一次移动中捕获到的卒的数量。

示例

输入:
[[".",".",".",".",".",".",".","."],
[".",".",".","p",".",".",".","."],
[".",".",".","p",".",".",".","."],
["p","p",".","R",".","p","B","."],
[".",".",".",".",".",".",".","."],
[".",".",".","B",".",".",".","."],
[".",".",".","p",".",".",".","."],
[".",".",".",".",".",".",".","."]]
输出: 3
解释: 车可以捕获位置 b5,d6 和 f5 的卒。

解答

class Solution {
public:
    int numRookCaptures(vector<vector<char>>& board) {
        int m = 0, n = 0, res = 0;
        for (; m < 8; m++)
            for (n = 0; n < 8; n++)
                if (board[m][n] == 'R') goto outer;
        outer : int a[4] = {0, 0, 1, -1};
        int b[4] = {1, -1, 0, 0};
        for (int i = 0; i < 4; i++)
            res += check(board, m, n, a[i], b[i]);
        return res;
    }
private:
    int check(vector<vector<char>>& board, int m, int n, int dx, int dy) {
        while (m >= 0 && n >= 0 && m < 8 && n < 8 && board[m][n] != 'B') {
            if (board[m][n] == 'p') return 1;
            m += dx;
            n += dy;
        }
        return 0;
    }
};

重点思路

就是先找车在哪,然后从车出发上下左右找一遍,这一阶段可以用4个for循环,但这道题最重要的一个知识点就是a和b的方向数组,这个在DFS中也有运用,在这里可以通过调用函数传入方向数组精简代码。另外注意学习此处直接跳出多重循环的goto用法。

posted @ 2021-02-07 16:11  tmpUser  阅读(44)  评论(0编辑  收藏  举报