【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
用法。