问题描述: 在一个五子棋棋盘上,已经有一些白色棋子摆放在棋盘上。现在你手中有一个白色棋子,任务是找出在棋盘上哪些位置放置这个棋子,可以形成五颗棋子连成一线。连成一线的五个棋子可以是横向、纵向或斜向排列。 思路解析 遍历棋盘上的每个空位置:
对于每个空白位置,我们可以尝试在该位置放置一个新的棋子,接着检查是否会形成五子连线。 检查五子连线:
对于每个空位置(假设我们放置了一个新的棋子),我们需要检查其周围的四个方向:横向、纵向、以及两条对角线。 检查一个方向时,我们需要向该方向和反方向两个方向进行遍历,计算连成一线的棋子数量。 如果在任何方向上连成五颗棋子,则返回该位置。 优化方向的判断:
五子棋的连线检查可以分为四个方向: 横向(右移) 纵向(下移) 主对角线(右下方向) 副对角线(右上方向) 返回结果:
对于每个符合条件的空白位置,返回其坐标(记得转化为1-based索引)。 def solution(n, array): def check_five_in_a_row(x, y): # 检查横向、纵向、对角线是否能形成五子连线 directions = [(1, 0), (0, 1), (1, 1), (1, -1)] for dx, dy in directions: count = 1 # 当前位置的棋子计为1 # 向一个方向检查 for i in range(1, 5): nx, ny = x + i * dx, y + i * dy if 0 <= nx < n and 0 <= ny < n and array[nx][ny] == 1: count += 1 else: break # 向反方向检查 for i in range(1, 5): nx, ny = x - i * dx, y - i * dy if 0 <= nx < n and 0 <= ny < n and array[nx][ny] == 1: count += 1 else: break if count >= 5: return True return False
result = []
for i in range(n):
for j in range(n):
if array[i][j] == 0: # 找到空位
if check_five_in_a_row(i, j):
result.append([i + 1, j + 1]) # 转换为1-based坐标
return result
if name == "main": array = [ [0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0], ]
print(solution(6, array) == [[1, 1], [6, 6]]) # 预期输出:[1, 1] 和 [6, 6]
代码详解 check_five_in_a_row(x, y):
该函数用于检查在位置 (x, y) 放置一个棋子后,是否能够形成五子连线。 方向:我们定义了四个方向:横向 (1, 0)、纵向 (0, 1)、主对角线 (1, 1) 和副对角线 (1, -1)。 遍历方向:对于每个方向,首先计算当前点开始的连线,接着再反向检查,看是否能连成五子。 如果在任意一个方向上可以连成五个棋子,则返回 True。 solution(n, array):
该函数遍历整个棋盘,对于每个空位(值为 0),调用 check_five_in_a_row 检查是否能形成五子连线。 如果可以形成五子连线,则将该位置加入 result。 最终返回所有符合条件的位置,注意返回的坐标是1-based的。
新知识点总结 方向的利用:
在解决类似五子棋的问题时,通过设定多个方向(如横向、纵向、斜向),可以高效地检查是否能形成连续的棋子。 空间的有效利用:
通过合理的坐标变换,避免了重复计算,提高了算法的效率。 边界判断:
在遍历方向时,必须时刻注意边界条件,确保计算不越界。
学习建议 掌握坐标变换与边界判断:
在解决类似问题时,坐标变换和边界判断是核心部分,务必熟练掌握。 多练习方向遍历:
本题涉及的方向遍历技巧是很多问题的通用解法,建议多做相关题目以提高解题效率。 理解五子棋问题的多方向检查:
五子棋的连线不仅涉及横向、纵向,还需要考虑对角线方向。掌握这些方向的检查方法对解决复杂的棋盘问题非常有帮助。