算法入门(5)枚举法(熄灯问题)

参考该链接和B站上的视频做一些简单的拓展。
题目描述:
有一个5行6列的按钮矩阵,矩阵中每一个位置都有一个灯和一个按钮。
当按下某个位置下按钮后该位置和该位置周围(上,下,左,右)的灯的状态都会改变依次。
如果该位置在矩阵边上只会改变周围3个位置灯的状态,如果在角上只会改变周围两个位置灯的状态。如下图所示(复制北大mooc上的图):
按中间的那个按钮,周围四个位置的灯状态都发生了改变。
问题:给定矩阵的初始状态,求一种按钮的方案能够将矩阵中所有的灯熄灭。
输入:
一个5*6的矩阵代表着灯的初始状态。(其中1表示灯亮着状态,0表示表示灯熄灭状态)
0 1 1 0 1 0
1 0 0 1 1 1
0 0 1 0 0 1
1 0 0 1 0 1
结果:
将矩阵轴的按钮按照以下方案进行操作能够让所有的灯熄灭。(其中 1表示按下该按钮,0标注无须操作)
1 0 1 0 0 1
1 1 0 1 0 1
0 0 1 0 1 1
1 0 0 1 0 0
0 1 0 0 0 0

解题思路:
首先这是一道比较复杂的枚举题目。首先要根据已知推测隐含的条件。
1.一个位置灯的状态不仅受该位置按钮的影响也受周围按钮的影响。
2.每一个位置的按钮状态只有0未操作和1操作两种状态。如果对同一个位置按钮操作两次,操作结果抵消。相当于未对该位置的按钮进行操作。因此对一个位置的按钮的操作只有两种状态。
3.一共有5*6=30个按钮如果我们枚举出对按钮操作的所有可能情况是否可以通过其操作后的结果去判断该情况是否可以让所有的灯全部熄灭。
4.如果上述3是准确的话是否还有其他方法去找让全部灯熄灭的方案。
5.在这里我们不妨这样考虑一下啊,1.首先第一行一共有6个按钮我们先对这六个按钮的操作进行假设一共能得到64个操作方案。通过这64个操作方案我们能够得到64个操作后的结果。这时候如果第一排还有灯没有熄灭,又因为我们已经对第一排的按钮执行过了相应的操作,这时候如果我们想关闭第一排的灯的话只能通过第二排的按钮进行操作。对第二排操作完成后,如果想要关闭第二排的灯只能通过第三排的按钮进行操作…一直到操作到第五排。如果在操作完第五排后所有灯熄灭了,那么这个方案就是可行的,如果第五排未关闭完,那么该方案不可行。
在5 我们需要两个操作:

  1. press[r+1][c]=(puzzle[r][c]+press[r][c]+press[r-1][c]+press[r][c-1]+press[r][c+1]) % 2(press是按钮操作矩阵,puzzle是初始状态矩阵。这个式子的含义是:第r+1行第c列按钮是否需要按下,根据该位置灯的初始状态和该位置前边,后边,左右和右边的按钮对该位置的操作去判断。换句话说也就是该位置的灯灯状态由一个初始状态和前左右,本身四个位置的按钮对该位置灯的操作决定。因此我们需要先通过前左右和本身四个位置的按钮对r行c列位置灯操作后的结果。然后如果计算出为1的话我们需要通过 press[r+1][c]关闭它,为0的话不用管了。)
  2. if (press[5][c-1]+press[5][c]+press[5][c+1]+press[4][c])%2!=puzzle[5][c](如果第五行c列的初始状态和第五行c列周围操作叠加操作不一样,那么灯就不会完全被熄灭。如第五行c列灯为1,四个操作叠加状态为(1+1+1+1)%2=0,则第五行第c列的灯未被关闭。 )
  3. emmmm。。。。python代码还没写出来。等等再放吧。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值