【一起来刷Python题】——09.解决熄灯问题

刷Python算法题第9天,想要分享的东西提上日程...🌈 接受失败而不气馁才是对勇气最大的考验。

        问题描述:有一个由按钮组成的矩阵,其中每行有6个按钮,共5行。每个按钮的位置上有一盏灯。当按下一个按钮后,该按钮以及周围位置(上边、下边、左边、右边)的灯都会改变一次。即如果灯原来是点亮的,就会被熄灭;如果灯原来是熄灭的,则会被点亮。在矩阵角上的按钮改变3盏灯的状态;在矩阵边上的按钮改变4盏灯的状态;其他的按钮改变5盏灯的状态。例如在图1中,左边矩阵中用X标记的按钮表示被按下,右边的矩阵表示灯状态的改变。对矩阵中的每一盏灯设置一个初始状态。请你按按钮,直至每一盏灯都熄灭。与每一盏灯毗邻的多个按钮被按下时,一次操作会抵消另一次操作的结果。

图1 

        在图2中,第2行第3、5列的按钮都被按下,因此第2行、第4列的灯的状态就不会发生改变。

图2

        请你写一个程序,确定需要按下哪些按钮,恰好使得所有的灯都被熄灭。

输入:5行组成,每一行包括6个数字(0或1)。相邻两个数字之间用单个逗号隔开。0表示灯的初始状态是熄灭的,1表示灯的初始状态是点亮的。

输出:5行组成,每一行包括6个数字(0或1)。 相邻两个数字之间用单个空格隔开。其中的1表示需要把对应的按钮按下,0则表示不需要按对应的按钮。

import numpy as np

line = [[0] * 6] * 5
for i in range(5):
    line[i] = input("请输入第" + str(i) + "行: ").split(',')
    # 将line中的元素转换为整型
    line[i] = list(map(int, line[i]))

puzzle = np.array(line)
zero = np.zeros(6)
# 向puzzle中的最上面加入一行0
puzzle = np.insert(puzzle, 0, values=zero, axis=0)
# 向puzzle中的最后一列加入一列0
puzzle = np.insert(puzzle, 6, values=zero, axis=1)
# 向puzzle中的第0列加入一列0
puzzle = np.insert(puzzle, 0, values=zero, axis=1)

b = [[0 for col in range(8)] for row in range(6)] # 创建6*8矩阵,6和8注意不要写反
press = np.array(b)
# 以上两句或者之间写为 press = np.zero(6,8)
def guess():
    for r in range(1, 5):
        for c in range(1, 7):
            # 根据press的第一行和puzzle的第一行,确定press其他行
            press[r+1][c] = (puzzle[r][c] + press[r][c] + press[r-1][c] + press[r][c-1] + press[r][c+1]) % 2
    # 判断所计算的press能否熄灭最后一行的所有灯,是则返回1,否则返回0
    for c in range(1, 7):
        if (press[5][c-1] + press[5][c] + press[5][c+1] + press[4][c]) % 2 != puzzle[5][c]:
            return 0
    return 1
# 枚举第一行按下开关的所有可能性,有2^6个
def enumeration():
    while guess() == 0: # 如果最后一行不熄灭所有的灯,将持续循环
        press[1][1] += 1 # 按下(1,1)位置的灯
        c = 1
        while(press[1][c] >1):  # 如果(1,c)的灯大于1,证明多按了一次,恢复熄灭状态
            press[1][c] = 0
            c +=1
            press[1][c] +=1

enumeration()
print("灯的初始状态:\n", puzzle[1:6, 1:7])
print("按下结果为:\n", press[1:6, 1:7])

代码思路:

        当按下第一行的按钮,对于第一行仍亮着的灯,由第二行按钮控制,以此类推,前四行同理,第五行如果全部熄灭,则第一行按钮的方式正确,否则,换一种第一行按钮按下的方式。对于初始矩阵(5*6),第一行按钮按下的状态有2^6(64)种。

        灯最后的状态(是否按下一行开关之前)与自身的状态、上、左、右按钮的操作有关,考虑到两次操作会抵消,则求他们操作的和与2的余数,为0,则熄灭,为1,则亮灯。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花落指尖❀

您的认可是小浪宝宝最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值