文章目录

  • 题目描述
  • 基本思路
  • 代码解释(解释在注释中)

题目描述

你玩过“拉灯”游戏吗?

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

基本思路

  1. 可以先遍历第一行,试试第一行的所有情况。
  2. 在进行下面四行时,可以根据上一行这个位置灯的状态判断是否要点灯
  3. 一直到第五行操作结束后,此时前四行为全亮,只需判断第五行是否有暗即可

代码解释(解释在注释中)


#include <iostream>
#include <cstring>using namespace std;// 如果要次数最少,每个灯的只能点一次,点两次相当于没点。
// 点每个位置的灯没有先后顺序,所以可以从第一行按顺序点灯
// 先对第一行的五个灯做出选择,再根据第一行的灯的状态来点第二行的灯,以此类推
// 统计点灯次数最少的次数
// 每次点灯,灯暗时状态变为亮,灯亮时状态转为暗// 用g数组记录灯阵的状态
char g[10][10];
// 灯的初识状态不能改变,所以应该再开一个数组,在这个数组上对灯阵进行修改
char backup[10][10];// 定义两个数组分别代表行和列,每个数组有五个元素,分别表示原位置和上下左右
// 注:这里的x和y并非表示数学中的坐标,x表示行,y表示列
char dx[] = { 0,-1,1,0,0 }, dy[] = { 0,0,0,-1,1 };void turn(int x, int y)
{// a表示行,b表示列// 用for循环遍历原位置,以及上下左右四个位置// 若这个位置上为0变为1,为1变为0for (int i = 0; i < 5; i++){int a = x + dx[i], b = y + dy[i];// 这里使用异或操作符// 0和1的ASCII值分别为48和49// 根据异或的概念48^1为49,而49^1为48if (a >= 0 && a <= 4 && b >= 0 && b <= 4){backup[a][b] ^= 1;}}
}// 在work函数中对灯阵进行判断
int work()
{// 定义一个应该返回的值,这个返回值要大于6,与后面点灯的次数作判断int ans = 100;// 0到31有5个正在改变的二进制位,每个二进制位的0和1表示第一行的灯的状态// 且每个二进制位对应一个灯的位置for (int k = 0; k < 1 << 5; k++){int num = 0; // 记录每个方法点灯的次数memcpy(backup, g, sizeof(g)); // 将灯的初识状态拷贝给新数组// 对第一行进行点灯,k不同点灯的情况就不同for (int j = 0; j < 5; j++){// 移位操作符的优先级大于按位与操作符,将k右移j位再与上1可判断k的哪一位有1if ((k >> j & 1) == 1){// 如果这个位上为1,进行点灯,点灯的次数加1并且进入点灯函数num++;// 0表示为第一行,j表示为这行第几个灯turn(0, j);}}// 从第一行开始依此向下,遍历前四行// 在每行中,如果这行中某个位置灯为暗,对这个位置正下方进行点灯for (int i = 0; i < 4; i++){// 遍历这行中每个位置for (int j = 0; j < 5; j++){// 如果这个位置灯暗,点正下方位置的灯,并且次数加一if (backup[i][j] == '0'){num++;turn(i + 1, j);}}}// 上面的操作可以保证前四行的灯都在亮着,此时判断最后一行是否全亮即可// 先假设最后一行全亮bool is_successful = true;for (int j = 0; j < 5; j++){if (backup[4][j] == '0'){// 如果有暗的,赋值为falseis_successful = false;}}// 如果都在亮着,进行赋值if (is_successful == true){ans = min(ans, num);}}return ans <= 6 ? ans : -1;
}int main()
{// 定义灯阵的数量int n;scanf("%d", &n);// 用while循环输入每个灯阵while (n--){// 只用一个for循环就可以输出一个灯阵// 原因是将每行看成字符串,一次就可以输入一行,用for循环输入五行即可for (int i = 0; i < 5; i++){scanf("%s", g[i]);}// 在work函数中对这个灯阵进行判断,并用ret记录返回值。int ret = work();printf("%d\n", ret);}
}

蓝桥杯真题 - 费解的开关题解相关推荐

  1. # 2014年蓝桥杯真题CC++B组

    2014年蓝桥杯真题C/C++B组 1.啤酒和饮料 题目描述 啤酒每罐2.3元,饮料每罐1.9元,小明买了若干啤酒和饮料,一共花了82.3元. 我们还知道她买的啤酒比饮料的数量多,请你计算他买了几罐啤 ...

  2. 蓝桥杯真题2017-2021

    刷完近几年真题,感觉理解完之后,拿奖问题不大,本人这次获得2022年蓝桥杯javaB组省一,以下是历年javaB组省赛题目. 文章目录 2017年真题 一.购物单 二.纸牌三角形 三.承压计算 四.魔 ...

  3. 第六届蓝桥杯真题总结

    第六届蓝桥杯真题总结 第一题:奖券数目 有些人很迷信数字,比如带"4"的数字,认为和"死"谐音,就觉得不吉利.虽然这些说法纯属无稽之谈,但有时还要迎合大众的需求 ...

  4. 2016年第七届蓝桥杯真题解析JavaC组

    相关题目: 2016年第七届蓝桥杯真题解析JavaB组 2016年第七届蓝桥杯真题解析JavaC组 2017年第八届蓝桥杯真题解析JavaB组 2017年第八届蓝桥杯真题解析JavaC组 2018年第 ...

  5. python解答蓝桥杯真题2 猜年龄 美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学。他曾在19351936年应邀来中国清华大学讲学。。。

    python解答蓝桥杯真题2 猜年龄 美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学.他曾在1935~1936年应邀来中国清华大学讲学... 问题描述 全排列模板: 美国数学家维纳(N. ...

  6. 第五届蓝桥杯真题解析【JavaC组】

    第五届蓝桥杯真题解析[JavaC组] 业精于勤,荒于嬉:行成于思,毁于随.--韩愈 文章目录 ***第五届蓝桥杯真题解析[JavaC组]*** 前言 A:猜年龄 B:等额本金 C:猜字母 D:大衍数列 ...

  7. 【蓝桥杯真题】16天冲刺 Python

    距离比赛很快了,希望和我一起准备的PY党能更加熟练的掌握Python! 1.距离和(模拟赛填空题) 问题描述: 两个字母之间的距离定义为它们在字母表中位置的距离.例如 A和 C 的距离为 2,L 和  ...

  8. 蓝桥杯真题:三羊献瑞

    蓝桥杯真题:三羊献瑞 观查下面的加法算式: 其中相同的汉字代表相同的数字,不同的汉字代表不同的数字. 请你填写"三羊献瑞"所代表的4位数字(答案唯一),不要填写任何多余内容. 分析 ...

  9. 蓝桥杯python省赛冲刺篇2——常用算法的详细解析及对应蓝桥杯真题:打表模拟法、递推递归法、枚举法、贪心算法、差分与前缀和

    注意:加了题目链接 目录 注意:加了题目链接 一.打表模拟法 介绍 1. 算式问题 题目描述 解析与代码演示 2. 求值 题目描述 解析与代码演示 3. 既约分数 题目描述 解析与代码演示 4. 天干 ...

  10. 第十届蓝桥杯c语言试题,第十届蓝桥杯真题编程题1-7解析(高级组).pdf

    scratch 少儿编程第十届蓝桥杯真题 7 大家好 ~今天我们来讲解 scratch 蓝桥杯第十届编程大题的第七道题. 同样,这道题也是非常有难度的一道题.一起来看一下吧 解析: 女孩的程序 1.在 ...

最新文章

  1. Centos版Linux 一些常用操作命令
  2. CentOS6.5安装Redis3.2.8版本
  3. Visual Studio 2017 15.9 版本发布:推出全新的导入 / 导出配置功能
  4. oracle 多个with as
  5. java的super是什么意思_java中Super到底是什么意思?必须举例说明!
  6. python存储序列_python序列类型及一些操作
  7. appsetting mysql_给IConfiguration写一个GetAppSetting扩展方法(示例代码)
  8. 对HTTPCONNECTION的理解
  9. Ubuntu Server 16.04 安装并用两块硬盘做RAID1
  10. MySQL技术内幕 InnoDB存储引擎【一】
  11. 解析分级存储管理(HSM)
  12. linux中文件大小的分配,Linux创造固定的文件大小-预分配磁盘空间
  13. 【总结】6种机器学习中的优化算法:SGD,牛顿法,SGD-M,AdaGrad,AdaDelta,Adam
  14. 解决NBSI安装显示“MSINET.OCX组件无法加载或其中有组件失败”
  15. 综合评价方法之熵值法
  16. 色彩设计原理(里面有配色方案,也有配色网站)
  17. w ndows默认截图工具,windows截图工具快捷键
  18. Problem A: 小学生的算术题
  19. 电气器件系列二十四:电子式压力传感器PPG-D(1)
  20. python图像锐化,图像加强、锐化,利用 Python-OpenCV 来实现 4 种方法!

热门文章

  1. 在光伏并网柜保护监测领域安科瑞给出的解决方案
  2. Hdmi 和vga 接口有什么区别?
  3. A. Groundhog and 2-Power Representation (递归 高精度) 2020牛客暑期多校训练营(第九场)
  4. 自己画一块ESP32-C3 的开发板(立创EDA)(PCB到手)
  5. 怎么设计制作简洁实用的App交互界面
  6. STM32学习100步之第四十二步——触摸按键驱动程序
  7. vrchat模型房_vrchat人物模型 1.0 官方版
  8. android flash插件下载地址,adobe flash player
  9. 对图片或者PDF流文件加水印
  10. MATLAB:randn简介