On an 8 x 8 chessboard, there is one white rook. There also may be empty squares, white bishops, and black pawns. These are given as characters 'R', '.', 'B', and 'p' respectively. Uppercase characters represent white pieces, and lowercase characters represent black pieces.
The rook moves as in the rules of Chess: it chooses one of four cardinal directions (north, east, west, and south), then moves in that direction until it chooses to stop, reaches the edge of the board, or captures an opposite colored pawn by moving to the same square it occupies. Also, rooks cannot move into the same square as other friendly bishops.
Return the number of pawns the rook can capture in one move.
Example 1:
Input: [[".",".",".",".",".",".",".","."],[".",".",".","p",".",".",".","."],[".",".",".","R",".",".",".","p"],[".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".","."],[".",".",".","p",".",".",".","."],[".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".","."]]
Output: 3
Explanation:
In this example the rook is able to capture all the pawns.
Example 2:
Input: [[".",".",".",".",".",".",".","."],[".","p","p","p","p","p",".","."],[".","p","p","B","p","p",".","."],[".","p","B","R","B","p",".","."],[".","p","p","B","p","p",".","."],[".","p","p","p","p","p",".","."],[".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".","."]]
Output: 0
Explanation:
Bishops are blocking the rook to capture any pawn.
Example 3:
Input: [[".",".",".",".",".",".",".","."],[".",".",".","p",".",".",".","."],[".",".",".","p",".",".",".","."],["p","p",".","R",".","p","B","."],[".",".",".",".",".",".",".","."],[".",".",".","B",".",".",".","."],[".",".",".","p",".",".",".","."],[".",".",".",".",".",".",".","."]]
Output: 3
Explanation:
The rook can capture the pawns at positions b5, d6 and f5.
Note:
board.length == board[i].length == 8
board[i][j]
is either'R'
,'.'
,'B'
, or'p'
- There is exactly one cell with
board[i][j] == 'R'
這道題給了一個 8x8
大小的國際象棋棋盤,上面只能有三種棋子,分別是白方的車,白方的象,和黑方的兵,問白色方的車最多能吃到多個黑方的兵。在國際象棋中,車是可以上下左右走的,若某條路徑上先遇到了白方的象,則該路上沒法吃兵了,若先遇上了兵,可以吃,但此時后面若還有兵,不能連續吃。搞懂了題意其實很簡單了,首先遍歷棋盤,找到白方車的位置,然后最簡單粗暴的方法是,四個方向分別用 for 循環來遍歷,若遇到白方的象,直接 break,若遇到兵,則結果 res 自增1,然后 break 即可,參見代碼如下:
解法一:
class Solution {
public:
int numRookCaptures(vector<vector<char>>& board) {
int x = 0, y = 0, res = 0;
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
if (board[i][j] == 'R') {
x = i; y = j; break;
}
}
}
for (int j = y; j >= 0; --j) {
if (board[x][j] == 'B') break;
if (board[x][j] == 'p') {++res; break;}
}
for (int j = y; j < 8; ++j) {
if (board[x][j] == 'B') break;
if (board[x][j] == 'p') {++res; break;}
}
for (int i = x; i >= 0; --i) {
if (board[i][y] == 'B') break;
if (board[i][y] == 'p') {++res; break;}
}
for (int i = x; i < 8; ++i) {
if (board[i][y] == 'B') break;
if (board[i][y] == 'p') {++res; break;}
}
return res;
}
};
我們也可以不用寫那么 for 循環,而是利用深度優先遍歷 DFS 的思想,用方向數組,每次加上方向的偏移,若沒有越界,則判斷,若是黑兵,則結果 res 加1,若不是點,則 break,這判斷很精髓,覆蓋了當前是白象或黑兵的情況,保證了遇到了白象,或者已經吃了黑兵之后可以 break,然后繼續增加偏移量直至退出循環,參見代碼如下:
解法二:
class Solution {
public:
int numRookCaptures(vector<vector<char>>& board) {
int x0 = 0, y0 = 0, res = 0;
vector<vector<int>> dirs{{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
if (board[i][j] == 'R') {
x0 = i; y0 = j; break;
}
}
}
for (auto &dir : dirs) {
int x = x0 + dir[0], y = y0 + dir[1];
while (x >= 0 && x < 8 && y >= 0 && y < 8) {
if (board[x][y] == 'p') ++res;
if (board[x][y] != '.') break;
x += dir[0]; y += dir[1];
}
}
return res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/999
參考資料:
https://leetcode.com/problems/available-captures-for-rook/