1. 问题描述:

你玩过"拉灯"游戏吗?25 盏灯排成一个 5×5 的方形。每一个灯都有一个开关,游戏者可以改变它的状态。每一步,游戏者可以改变某一个灯的状态。游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也要相应地改变其状态。我们用数字 1 表示一盏开着的灯,用数字 0 表示关着的灯。下面这种状态
10111
01101
10111
10000
11011

在改变了最左上角的灯的状态后将变成:
01111
11101
10111
10000
11011

再改变它正中间的灯后状态将变成:
01111
11001
11001
10100
11011
给定一些游戏的初始状态,编写程序判断游戏者是否可能在 6 步以内使所有的灯都变亮。

输入格式

第一行输入正整数 n,代表数据中共有 n 个待解决的游戏初始状态。以下若干行数据分为 n 组,每组数据有 5 行,每行 5 个字符。每组数据描述了一个游戏的初始状态。各组数据间用一个空行分隔。

输出格式

一共输出 n 行数据,每行有一个小于等于 6 的整数,它表示对于输入数据中对应的游戏状态最少需要几步才能使所有灯变亮。对于某一个游戏初始状态,若 6 步以内无法使所有灯变亮,则输出 −1。

数据范围

0 < n ≤ 500

输入样例:

3
00111
01011
10001
11010
11100

11101
11101
11110
11111
11111

01111
11111
11111
11111
11111

输出样例:

3
2
-1
来源:https://www.acwing.com/problem/content/97/

2. 思路分析:

首先比较容易想到的是先做一遍预处理,从终止状态逆推6步看可以到达哪一些状态,相当于是一个打表的形式,因为是5 * 5的方阵所以最多有3.2 * 10 ^ 7个状态,而且每一次需要将得到的方阵转换为对应的状态,当我们输入对应状态的时候判断是否可以由终止状态转移过来,如果可以说明是合法的状态,但是这种做法时间复杂度比较难估计,这里其实有一个更保险的做法,当前位置灯的状态只取决于上下左右四个灯的摁的次数,所以我们可以尝试使用递推的方法来解决,从上往下开始递推,假设第一行的状态已经被确定了,也即不能够再修改第一行灯的状态了,通过对应的方阵可以发现后面每一行的状态都是确定的,我们可以从第一行开始枚举,一直到第四行,如果当前的位置为0说明需要摁下一行的灯的状态,这样当前灯的状态就改变了,如果是1说明不用改变,我们可以从第一行递推到第四行最终判断最后一行灯的状态,如果灯是全亮的并且答案更小那么更新答案。由于第一行的状态是不确定的,有5盏灯所以有2 ^ 5个状态,只需要枚举0~31即可,将对应位置为1的灯摁一下即可。时间复杂度为O(500 * 32 * 25 * 5) = 2000000.

3. 代码如下:

from typing import Listclass Solution:# 摁一下第x行y列的灯, 在摁的时候修改当前位置上下左右以及当前位置灯的状态, 将0变成1, 将1变成0可以使用异或操作来解决def turn(self, x: int, y: int, g: List[List[int]]):pos = [[-1, 0], [1, 0], [0, -1], [0, 1], [0, 0]]for i in range(5):a, b = x + pos[i][0], y + pos[i][1]if 0 <= a < 5 and 0 <= b < 5:g[a][b] ^= 1def process(self):T = int(input())while T:bg = list()# 将输入的字符串转换为int类型的二维列表数据for i in range(5):bg.append(list(map(int, list(input()))))res = 10# 枚举第一行所有可能的状态for i in range(32):g = list()count = 0# # 在尝试每一个状态的时候需要将g恢复到之前的状态, 这里使用一个备份的列表bg拷贝副本到g中for j in range(5):g.append(bg[j][:])# 修改当前第一行对应位置为1的灯的状态for k in range(5):if i >> k & 1:self.turn(0, k, g)count += 1# 第一行位置灯的状态已经确定了for j in range(4):for k in range(5):if g[j][k] == 0:# 摁下一行灯的状态self.turn(j + 1, k, g)count += 1success = 1# 枚举最后一行灯的状态判断是否有不亮的灯for j in range(5):if g[4][j] == 0: success = 0if success and res > count: res = count# 答案大于6无解if res > 6: res = -1print(res)T -= 1# 接受空行if T:input()if __name__ == "__main__":Solution().process()

95 费解的开关(递推)相关推荐

  1. AcWing 95. 费解的开关 Python详解

    一.算法思想--递推(详细证明见算法竞赛进阶指南原书) 1)若固定第1行,则方案至多只有1种 2)把第1行的所有情况遍历,先把亮着的灯全部关闭 3)遍历前4行,如果灯是关着的,就把下1行同1列的灯改变 ...

  2. AcWing 95. 费解的开关(指数型枚举)

    95. 费解的开关 题意: 给定一个5x5的方格,共25盏灯 每盏灯有开和关两种状态 每次操作一盏灯时,以该灯为中心的十字形状范围的灯都会改变状态 找到用最少的操作步数使所有的灯都亮着,当步数超过6时 ...

  3. 《算法竞赛进阶指南》打卡-基本算法-AcWing 95. 费解的开关:位运算、枚举、递推

    文章目录 题目解答 题目来源 题目解答 分析: 枚举第一行,指的是第一行哪些位置要切换状态!!!.第一行总共有5个数,组合数是32,即第一行哪些位置要切换总共有32种情况.这就是我们的枚举空间.比如, ...

  4. 题解【acwing】95 费解的开关

    题目描述 点击进入题目 你玩过"拉灯"游戏吗?25盏灯排成一个5x5的方形.每一个灯都有一个开关,游戏者可以改变它的状态.每一步,游戏者可以改变某一个灯的状态.游戏者改变一个灯的状 ...

  5. 95. 费解的开关【二级制枚举】

    二进制枚举第一行的操作状态. #include<bits/stdc++.h> using namespace std; const int N=30; char a[N][N],b[N][ ...

  6. AcWing 95. 费解的开关

    原题链接:https://www.acwing.com/problem/content/97/ 看了前几篇题解和y总的视频讲解,总有一个奇怪的点搞不明白,为什么说第一行确定了,第二行就确定了,第三行接 ...

  7. 0x02.基本算法 — 递推与递归

    目录 一.递推与递归 二.分治 三.模拟计算机实现递归 四.相应习题: 0.AcWing 92. 递归实现指数型枚举(递归/循环+位运算) 1.AcWing 93. 递归实现组合型枚举 2.AcWin ...

  8. 第一章:递推与递归 【完结】

    目前,这一章都已经熟练掌握了. 目录 92. 递归实现指数型枚举 [板子题] 94. 递归实现排列型枚举 [板子题] 93. 递归实现组合型枚举[板子题] 717. 简单斐波那契 [简单 / 递推] ...

  9. 蓝桥杯C++ AB组辅导课 第一讲 递归与递推 Acwing

    例题 AcWing 92. 递归实现指数型枚举 从 1∼n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案. 输入格式 输入一个整数 n. 输出格式 每行输出一种方案. 同一行内的数必须升序 ...

  10. 递归与递推类型题小结

    文章目录 1. 递归 1.1 解题思想 1.2 例题1(指数型枚举) 题意: 思路: 递归树模型: 时间复杂度: 代码实现: 1.3 例题2(排列型枚举) 题意: 思路: 递归树模型: 时间复杂度分析 ...

最新文章

  1. 使用 iPerf 测试 Azure VM 之间的网速
  2. go 根据输入类型执行对应的方法_安全很重要:Go项目的安全评估技术
  3. Verilog HDL常用循环语句类型
  4. 在 GitHub 上提交代码必备指南!
  5. 读《编码-藏匿在计算机软硬件背后的语言》有感
  6. 解决问题 1474 个,Flink 1.11 究竟有哪些易用性上的改善?
  7. python下载豆丁文档_doc_downloader
  8. python程序设计总结报告_把PPT 总结报告上传
  9. python中的scaler_使用时值错误scaler.inverse_变换在Python中
  10. Filter 过滤器使用
  11. c 朗读html,朗读《送杜少府之任蜀》
  12. 上海电信账单余额查询接口
  13. Hive数据库创建表
  14. Vue使用Object标签对接IC读卡器硬件
  15. 会声会影x4素材_会声会影素材包
  16. 【virtualbox】虚拟机virtualbox mac版使用教程
  17. 如何识别哭泣csdn_你上一次流泪是什么时候?| 研究:几乎不哭泣的4类人
  18. griffin-lim算法及 vocoder声码器
  19. 20145124 《Java程序设计》第10周学习总结
  20. WaSP的简要历史以及为何Web标准很重要

热门文章

  1. 洛谷1315 观光公交(贪心)
  2. 不存在R上的连续函数f,它在无理数集R\Q上是一一映射,而在有理数集Q上不是一一映 射。
  3. AUTOSAR入门介绍
  4. 添闻地图商户采集教程-含高德、腾讯、百度
  5. google play连接超时_谷歌Play多年来一直传播高级安卓恶意软件,并曾被用于间谍活动!...
  6. 如何用计算机蓝牙发送文件,电脑怎么利用蓝牙使手机和电脑互传文件
  7. [POI2012]HUR-Warehouse Store(贪心,堆)
  8. 仿微博系统数据库设计和er图设计
  9. 易语言开发微信机器人插件
  10. 静态模型,动态模型!