参考TLE大佬
https://www.acwing.com/solution/content/6773/
# 解题关键
# 1. 对同一位置, 不可能点击两次, 否则为无效操作
# 2. 在1的基础上, 说明5*5数组, 最多改变25次
# 3. 为达到正确答案, 点的变化, 顺序无影响
# 4. 在3的基础上, 我们只需要找到要改变的坐标数, 等价于改变几次
# 5. 每一行数值的改变, 可以通过上一行, 当前行, 下一行改变.
# 6. 在5的基础上, 如果某一行已确定(不能通过该行更改), 那么只能通过它的上一行或下一行修改该行现存的"0"
# 7. 在6的基础上, 当第一行确定时, 只能通过第2行改变. 当第一行全为1时, 第二行就无法通过该行改变, 否则会影响第一行的布局, 所以只能通过
#第3行改变, 依次类推
# 8. 在7的基础上, 进行到最后一行时, 它已无法做任何修改(它没有下一行). 故判断它是否都为"1"就可以了
python 代码
def turn(arr, i, j):
'''
控制灯的改变
参数:
arr 5*5数组
i 横坐标
j 纵坐标
返回值:
new_arr 改变后的5*5数组
'''
dx = [0, -1, 0, 1, 0]
dy = [0, 0, -1, 0, 1]
for index in range(5):
new_i = i + dx[index] # 有的时候, 不变也是一种变化
new_j = j + dy[index]
if 0<=new_i<5 and 0<=new_j<5:
arr[new_i][new_j] ^= 1 # 对于0,1之间的变化, 用异或^操作符
def my_work(arr):
res = 25 # 某种意义上的最大值
for k in range(32):
# print(arr)
cnt = 0 # 记录每次新第一行的状态
temp_arr = [list(x) for x in arr] # 记录旧的状态, 想要保证创建的列表不同, 必须保证内部元素不可变
for i in range(5):
if (k >> i & 1): # 对于数字数据, 可以考虑二进制模式的规律
turn(temp_arr, 0, i)
cnt += 1
for i in range(4):
for j in range(5):
if temp_arr[i][j] == 0:
turn(temp_arr, i+1, j)
cnt += 1
# print("2: ", cnt)
is_successful = True
for i in range(5):
if temp_arr[4][i] == 0:
is_successful = False
break
if is_successful:
res = cnt if res>cnt else res
k += 1
# print(res)
if res <= 6:
return res
else:
return -1
n = int(input())
res_list = []
while n>0:
arr = []
for i in range(5):
arr.append([int(x) for x in input()])
res_list.append(my_work(arr))
n -= 1
if n != 0:
input()
for i in res_list:
print(i)