车的可用捕获量
题目
在一个 8 x 8 的棋盘上,有一个白色车(rook)。也可能有空方块,白色的象(bishop)和黑色的卒(pawn)。它们分别以字符 “R”,“.”,“B” 和 “p” 给出。大写字符表示白棋,小写字符表示黑棋。
车按国际象棋中的规则移动:它选择四个基本方向中的一个(北,东,西和南),然后朝那个方向移动,直到它选择停止、到达棋盘的边缘或移动到同一方格来捕获该方格上颜色相反的卒。另外,车不能与其他友方(白色)象进入同一个方格。
返回车能够在一次移动中捕获到的卒的数量。
示例 1:
输入:
[[".", ".", ".", ".", ".", ".", ".", "."],
[".", ".", ".", "p", ".", ".", ".", "."],
[".", ".", ".", "R", ".", ".", ".", "p"],
[".", ".", ".", ".", ".", ".", ".", "."],
[".", ".", ".", ".", ".", ".", ".", "."],
[".", ".", ".", "p", ".", ".", ".", "."],
[".", ".", ".", ".", ".", ".", ".", "."],
[".", ".", ".", ".", ".", ".", ".", "."]]
输出:3
解释:
在本例中,车能够捕获所有的卒。
示例 2:
输入:
[[".", ".", ".", ".", ".", ".", ".", "."],
[".", "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", ".", "."],
[".", ".", ".", ".", ".", ".", ".", "."],
[".", ".", ".", ".", ".", ".", ".", "."]]
输出:0
解释:
象阻止了车捕获任何卒。
示例 3:
输入:
[[".", ".", ".", ".", ".", ".", ".", "."],
[".", ".", ".", "p", ".", ".", ".", "."],
[".", ".", ".", "p", ".", ".", ".", "."],
["p", "p", ".", "R", ".", "p", "B", "."],
[".", ".", ".", ".", ".", ".", ".", "."],
[".", ".", ".", "B", ".", ".", ".", "."],
[".", ".", ".", "p", ".", ".", ".", "."],
[".", ".", ".", ".", ".", ".", ".", "."]]
输出:3
解释:
车可以捕获位置 b5,d6 和 f5 的卒。
提示:
- board.length == board[i].length == 8
- board[i][j] 可以是 ‘R’,’.’,‘B’ 或 ‘p’
- 只有一个格子上存在 board[i][j] == ‘R’
上面图源均来自 LeetCode
解题思路
稍微吐槽一下,这道题目从文字方面理解题意,总会有很多困扰的地方(下面会提及)。这里结合示例来理解:
- 白色车(rook,主角)
- 白色的象(bishop,友方),黑色的卒(pawn,姑且叫敌方),要捕获黑色的卒。
困扰的地方 1:
选择四个基本方向中的一个(北,东,西和南),然后朝那个方向移动,直到它选择停止、到达棋盘的边缘或移动到同一方格来捕获该方格上颜色相反的卒
后面部分的内容,的确有点拗口(移动到同一方格捕获该方格颜色相反的卒),其实这里表示当找到车(R)的时候,就这个车的角度出发,选择北,南,西和东(也就是上下左右),确认可以捕获黑色的卒的数量。
困扰的地方 2:
返回车能够在一次移动中捕获到的卒的数量。
这里单从文字上来看,觉得就是车(R)选择一个方位,一次移动捕获的卒(p)的数量。但结合示例来看,这里的一次,表示的是【北,南,西,东】四个方位算一次。这里有个需要注意的地方,看示例 3,当同个方位有两个黑色的卒时,车(R)只捕获先暴露在面前的卒,后面的卒并不会被捕获。
理解题意后,大致说下解题的思想:
- 先处理边界问题,防止棋跳出棋盘;
- 如果遇到白色的象(B,友方),这个时候要停止,因为不能同时在同一个方格中;
- 如果遇到黑色的卒(p,敌方),说明找到捕获对象,返回值 + 1;
- 如果遇到的
.
(在这里表示空的棋格),表示可以继续移动;
代码实现
class Solution:
def numRookCaptures(self, board: List[List[str]]) -> int:
def move(board, x, y, direction):
# 约束在棋盘内
while x >= 0 and x < 8 and y >= 0 and y < 8:
# 遇到象停止
if board[x][y] == 'B':
break
# 遇到黑色卒捕获
if board[x][y] == 'p':
return True
# 继续移动
x += direction[0]
y += direction[1]
return False
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
for x in range(8):
for y in range(8):
# 先定位车(R)的位置
if board[x][y] == 'R':
res = 0
# 向四个方位移动,
for direction in directions:
if move(board, x, y, direction):
res += 1
return res
实现结果
以上就是通过解析题意,根据题意所述的规则直接模拟象棋的移动,从而解决《车的可用捕获量》问题的主要内容。
共同学习,写下你的评论
评论加载中...
作者其他优质文章