题目描述: 围棋棋盘由纵横各19条线垂直相交组成,棋盘上一共19x19=361个交点,对弈双方一方执白棋,一方执黑棋,落子时只能将棋子置于交点上。 “气”是围棋中很重要的一个概念,某个棋子有几口气,是指其上下左右方向四个相邻的交叉点中,有几个交叉点没有棋子,由此可知: 1、在棋盘的边缘上的棋子最多有3口气(黑1),在棋盘角点的棋子最多有2口气(黑2),其它情况最多有4口气(白1) 2、所有同色棋子的气之和叫作该色棋子的气,需要注意的是,同色棋子重合的气点,对于该颜色棋子来说,只能计算一次气, 比如下图中,黑棋一共4口气,而不是5口气,因为黑1和黑2中间红色三角标出的气是两个黑棋共有的,对于黑棋整体来说只能算一个气。 3、本题目只计算气,对于眼也按气计算,如果您不清楚“眼”的概念,可忽略,按照前面描述的规则计算即可。 现在,请根据输入的黑棋和白棋的坐标位置,计算黑棋和白棋一共各有多少气? 输入描述: 输入包括两行数据,如: 0 5 8 9 9 10 5 0 9 9 9 8 说明: 1、每行数据以空格分隔,数据个数是2的整数倍,每两个数是一组,代表棋子在棋盘上的坐标; 2、坐标的原点在棋盘左上角点,第一个值是行号,范围从0到18;第二个值是列号,范围从0到18。 输出: 8 7 说明: 黑棋有8口“气”,白棋有7口“气”
解题思路:
1、初始化棋盘:使用一个19x19的二维数组来表示棋盘,其中
0
表示空位,1
表示黑棋,2
表示白棋。2、将输入数据填入棋盘:将输入的黑棋和白棋的坐标填入棋盘,需单读处理白棋和黑棋的输入和气数。
3、计算气数:使用DFS遍历棋盘上的每一个位置,并计算每个棋子的气数:
·如果该位置没有棋子(即值为0),则检查其上下左右四个方向是否有棋子(黑棋或白棋)
·如果有,则根据棋子的颜色(黑棋或白棋)增加对应颜色的“气”的数量
·需要注意的是,同色棋子重合的气点只能计算一次
4、输出黑棋和白棋的总气数。
代码部分
#检查坐标(x,y)是否在棋盘范围内,防止DFS检查坐标越界
def in_bounds(x, y):
return 0 <= x <= 18 and 0 <= y <= 18
#使用DFS计算棋的气数
def dfs(board, x, y, color, visited):
stack = [(x, y)] #stack用于保存需要检查的棋子的坐标
# visited[x][y] = True #visited数组用于记录是否已经访问过该位置
qi = 0
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
while stack:
c_x, c_y = stack.pop()
#依次访问棋子的四个方位:左、右、下、上
for d_x, d_y in directions:
n_x, n_y = c_x + d_x, c_y + d_y
if in_bounds(n_x, n_y): #确认四个方向坐标位于棋盘中
if board[n_x][n_y] == 0 and not visited[n_x][n_y]: #此坐标没有棋子
visited[n_x][n_y] = True #此坐标已经访问,算入气中,确保同色棋子重合的气点只能计算一次
qi += 1
elif board[n_x][n_y] == color and not visited[n_x][n_y]: #此坐标有相同颜色棋子,但未曾被访问,压入栈中
visited[n_x][n_y] = True
stack.append((n_x, n_y)) #保证算法能够完整地探索所有与初始棋子相连的同色棋子
#else:此坐标存在另一种颜色棋子,不做任何操作
return qi
#计算指定颜色棋子的总气数
def calculate_qi(board, color):
visited = [[False for _ in range(19)] for _ in range(19)]
total_qi = 0
for i in range(19):
for j in range(19):
if board[i][j] == color and not visited[i][j]: #计算未访问过的对应color棋子的气
visited[i][j] = True
#将(i,j)处棋子访问标志置为1,这样dfs函数可省略visited[x][y] = True;
# 若不写,需要在dfs函数中将棋子访问标志置1
total_qi += dfs(board, i, j, color, visited)
return total_qi
def main():
#初始化棋盘
board = [[0 for _ in range(19)] for _ in range(19)]
"""
#直接输入棋盘的情况
board = []
for _ in range(19):
line = input().strip()
board.append([int(char) for char in line])
"""
#读取黑棋坐标
black_positions = list(map(int, input().split()))
for i in range(0, len(black_positions), 2):
x, y = black_positions[i], black_positions[i + 1]
board[x][y] = 1
#读取白棋坐标
white_positions = list(map(int,input().split()))
for i in range(0, len(white_positions), 2):
x, y = white_positions[i], white_positions[i + 1]
board[x][y] = 2
#计算黑白棋总气数
black_qi = calculate_qi(board, 1)
white_qi = calculate_qi(board, 2)
print(black_qi, white_qi)
if __name__ =='__main__':
main()
知识点:图、DFS、列表
结语:越简单的题目解法应该越多,请路过大神留下新的思路供本小白学习一下,打开思路