题目描述
张兵和王武是五子棋迷,工作之余经常切磋棋艺。这不,这会儿又下起来了。
走了一会儿,轮张兵了,对着一条线思考起来了,这条线上的棋子分布如下:
用数组表示: -1 0 1 1 1 0 1 0 1 -1
棋了分布说明:
-1代表白子,0代表空位,1 代表黑子
数组长度L,满足 1 < L < 40,L为奇数
你得帮他写一个程序,算出最有利的出子位置。 最有利定义:
找到一个空位(0),用棋子(1/-1)填充该位置,可以使得当前子的最大连续长度变大
如果存在多个位置,返回最靠近中间的较小的那个坐标
如果不存在可行位置,直接返回-1
连续长度不能超过5个(五字棋约束)
输入描述
第一行: 当前出子颜色
第二行: 当前的棋局状态
输出描述
1个整数,表示出子位置的数组下标
用例1
输入
1
-1 0 1 1 1 0 1 -1 1
输出
5
用例2
输入
1
-1 0 1 1 1 0 1 1 -1
输出
1
### 解题思路1.采用滑动窗口法,记录含一个0的最大的长度(小于6),遇到对方棋子时一切清零
2.注意遇到0时记录0的下标位置,遇到更大连续长度时,更新0的下标
考点
滑动窗口
python代码
def Wuzi_chess_Fan(color, chess_sts):
#滑动窗口求最大长度
#滑动窗口列表
list1=[]
max_length=0
min_coordinate=-1
list2=[] #储层空位索引的列表
for i in range(len(chess_sts)):
#情况 1 若与当前手的棋子相同,则加入列表中,不进行最小索引判断
if chess_sts[i] ==color:
list1.append(chess_sts[i])
'''
如果当前落子方为空位,则先判断list1是否有空,滑动窗口列表中只能有1个空位
1.有空位时list1需计算长度并赋值,如果截至当前的列表长度大于5,则不赋值;若小于5则将其赋值给最小索引
2.空位时直接将空位当己方棋子加入列表
'''
elif chess_sts[i]=='0':
if '0'in list1:
#先判断现有滑动窗口长度符合要求则赋值
if len(list1) > max_length and len(list1) <=5:
min_coordinate = list2[len(list2)-1]
max_length=len(list1)
#生成新的列表滑动窗口 ,先拿到已有的0的位置,再切片,最后加入新的0
j=list1.index('0')
list2.append(i)
list1=list1[j+1::]
list1.append('0')
else:
list1.append('0')
list2.append(i)
# 除了遇到0会终止,遇到-1也会终止
elif chess_sts[i]!='0' and chess_sts[i]!=color:
if len(list1) > max_length and len(list1) <= 5:
min_coordinate = list2[len(list2) - 1]
max_length = len(list1)
#只要不是当前输入颜色则滑动窗口都置空
list1=[]
#循环到最后时如果结尾为1则会少计算一次,即需要增加一次判断
if len(list1) > max_length and len(list1) <= 5:
min_coordinate = list2[len(list2) - 1]
max_length = len(list1)
return min_coordinate
if __name__=='__main__':
str1='1'
color=str1
#str='-1 0 1 1 1 0 1 1 -1 1 1 1 0 1'
#str='-1 0 1 1 1 0 1 -1 1'
str='-1 0 1 1 1 0 1 1 -1'
chess_sts=str.split()
min_coordinate=Wuzi_chess_Fan(color,chess_sts)
print(min_coordinate)
总结
- 该题特色是滑动窗口的大小是不固定的,需要考虑以何种方式拿到当前滑动窗口内的元素,比如记录对应索引位置对其切片
- 因其是取滑动窗口中的某位置元素,所以需要记录该元素的地址,以便切片
- 因最后一次遍历未遇到终止条件,需要增加一次判断