算法实践:熄灯问题(枚举)

2023-11-21 15:10

本文主要是介绍算法实践:熄灯问题(枚举),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

熄灯问题

描述

有一个由按钮组成的矩阵,其中每行有6个按钮,共5行。每个按钮的位置上有一盏灯。当按下一个按钮后,该按钮以及周围位置(上边、下边、左边、右边)的灯都会改变一次。即,如果灯原来是点亮的,就会被熄灭;如果灯原来是熄灭的,则会被点亮。在矩阵角上的按钮改变3盏灯的状态;在矩阵边上的按钮改变4盏灯的状态;其他的按钮改变5盏灯的状态。
img

在上图中,左边矩阵中用X标记的按钮表示被按下,右边的矩阵表示灯状态的改变。对矩阵中的每盏灯设置一个初始状态。请你按按钮,直至每一盏等都熄灭。与一盏灯毗邻的多个按钮被按下时,一个操作会抵消另一次操作的结果。在下图中,第2行第3、5列的按钮都被按下,因此第2行、第4列的灯的状态就不改变。
img

请你写一个程序,确定需要按下哪些按钮,恰好使得所有的灯都熄灭。根据上面的规则,我们知道1)第2次按下同一个按钮时,将抵消第1次按下时所产生的结果。因此,每个按钮最多只需要按下一次;2)各个按钮被按下的顺序对最终的结果没有影响;3)对第1行中每盏点亮的灯,按下第2行对应的按钮,就可以熄灭第1行的全部灯。如此重复下去,可以熄灭第1、2、3、4行的全部灯。同样,按下第1、2、3、4、5列的按钮,可以熄灭前5列的灯。

输入

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

输出

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

样例

2
0 1 1 0 1 0
1 0 0 1 1 1
0 0 1 0 0 1
1 0 0 1 0 1
0 1 1 1 0 0
0 0 1 0 1 0
1 0 1 0 1 1
0 0 1 0 1 1
1 0 1 1 0 0
0 1 0 1 0 0
PUZZLE #1
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 
PUZZLE #2
1 0 0 1 1 1 
1 1 0 0 0 0 
0 0 0 1 0 0 
1 1 0 1 0 1 
1 0 1 1 0 1 注意:PUZZLE行结尾没有空格,数字行最后有一个空格。

难度

高难度,枚举

解题思路

采用递归的方法枚举出第一行灯的亮灭情况,之后依次熄灭底下的灯来改变上一行灯的状态,执行到倒数第二行时如果灯全部灭,则熄灯成功。

代码

import numpy as np
# 枚举第一行的所有可能状态,关键所在
def all_status(status_list, status, depth):#初始status = 0rows, columns = status.shapeother = status.copy()other[0, depth] = 1if depth == columns - 1:status_list.append(status.copy())    status_list.append(other.copy())  else:all_status(status_list, status.copy(), depth + 1)  #对为0的情况递归all_status(status_list, other.copy(), depth + 1)  #对为1的情况实现递归# 如果按钮按下,更改灯的状态
def light_change(input_data, i, j):rows, columns = input_data.shapeinput_data[i, j] = (input_data[i, j] + 1) % 2if (i - 1) >= 0:input_data[i - 1, j] = (input_data[i - 1, j] + 1) % 2if (i + 1) < rows:input_data[i + 1, j] = (input_data[i + 1, j] + 1) % 2if (j - 1) >= 0:input_data[i, j - 1] = (input_data[i, j - 1] + 1) % 2if (j + 1) < columns:input_data[i, j + 1] = (input_data[i, j + 1] + 1) % 2# 尝试关闭所有灯
def light_off(input_data, output_data):rows, columns = input_data.shape# 根据第一行按钮的状态修改灯的亮灭for i in range(0, columns):if output_data[0, i] == 1:light_change(input_data, 0, i)# 从第二行开始,每一行的按钮都使上一行的灯熄灭for i in range(1, rows):for j in range(0, columns):if input_data[i - 1, j] == 1:light_change(input_data, i, j)output_data[i, j] = 1if np.sum(input_data) == 0:return True, output_dataelse:return False, output_data# 输出指定格式的结果
def print_result(output_data):rows, columns = output_data.shapefor i in range(rows):binary_string = ''for j in range(columns):binary_string =binary_string+ str(output_data[i, j] )+" "print(binary_string)#输入
input_list = []
number = (int)(input())
for i in range(number):input_data=np.ones((5,6),dtype=np.int16)for ii in range(5):n = input().split(' ')for iii in range(6):input_data[ii][iii] = n[iii]input_list.append(input_data)status_list = []
status = np.zeros((5, 6), dtype = 'int8')
all_status(status_list, status, 0)
for i in range(len(input_list)):input_data = input_list[i]for j in range(len(status_list)):flag, output_data = light_off(input_data.copy(), status_list[j].copy())if flag:#print(j)print('PUZZLE #%d' % (i + 1))print_result(output_data)break

这篇关于算法实践:熄灯问题(枚举)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/403140

相关文章

Java 的ArrayList集合底层实现与最佳实践

《Java的ArrayList集合底层实现与最佳实践》本文主要介绍了Java的ArrayList集合类的核心概念、底层实现、关键成员变量、初始化机制、容量演变、扩容机制、性能分析、核心方法源码解析、... 目录1. 核心概念与底层实现1.1 ArrayList 的本质1.1.1 底层数据结构JDK 1.7

JDK21对虚拟线程的几种用法实践指南

《JDK21对虚拟线程的几种用法实践指南》虚拟线程是Java中的一种轻量级线程,由JVM管理,特别适合于I/O密集型任务,:本文主要介绍JDK21对虚拟线程的几种用法,文中通过代码介绍的非常详细,... 目录一、参考官方文档二、什么是虚拟线程三、几种用法1、Thread.ofVirtual().start(

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

一文解析C#中的StringSplitOptions枚举

《一文解析C#中的StringSplitOptions枚举》StringSplitOptions是C#中的一个枚举类型,用于控制string.Split()方法分割字符串时的行为,核心作用是处理分割后... 目录C#的StringSplitOptions枚举1.StringSplitOptions枚举的常用

IDEA和GIT关于文件中LF和CRLF问题及解决

《IDEA和GIT关于文件中LF和CRLF问题及解决》文章总结:因IDEA默认使用CRLF换行符导致Shell脚本在Linux运行报错,需在编辑器和Git中统一为LF,通过调整Git的core.aut... 目录问题描述问题思考解决过程总结问题描述项目软件安装shell脚本上git仓库管理,但拉取后,上l

深入理解Mysql OnlineDDL的算法

《深入理解MysqlOnlineDDL的算法》本文主要介绍了讲解MysqlOnlineDDL的算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小... 目录一、Online DDL 是什么?二、Online DDL 的三种主要算法2.1COPY(复制法)

idea npm install很慢问题及解决(nodejs)

《ideanpminstall很慢问题及解决(nodejs)》npm安装速度慢可通过配置国内镜像源(如淘宝)、清理缓存及切换工具解决,建议设置全局镜像(npmconfigsetregistryht... 目录idea npm install很慢(nodejs)配置国内镜像源清理缓存总结idea npm in

pycharm跑python项目易出错的问题总结

《pycharm跑python项目易出错的问题总结》:本文主要介绍pycharm跑python项目易出错问题的相关资料,当你在PyCharm中运行Python程序时遇到报错,可以按照以下步骤进行排... 1. 一定不要在pycharm终端里面创建环境安装别人的项目子模块等,有可能出现的问题就是你不报错都安装

springboot依靠security实现digest认证的实践

《springboot依靠security实现digest认证的实践》HTTP摘要认证通过加密参数(如nonce、response)验证身份,避免明文传输,但存在密码存储风险,相比基本认证更安全,却因... 目录概述参数Demopom.XML依赖Digest1Application.JavaMyPasswo

idea突然报错Malformed \uxxxx encoding问题及解决

《idea突然报错Malformeduxxxxencoding问题及解决》Maven项目在切换Git分支时报错,提示project元素为描述符根元素,解决方法:删除Maven仓库中的resolv... 目www.chinasem.cn录问题解决方式总结问题idea 上的 maven China编程项目突然报错,是