【蓝桥杯备赛笔记 02】 费解的开关(模拟实现)

费解的开关

  • 【蓝桥杯备赛笔记 02】 费解的开关(模拟实现)
    • 解题思路
    • 代码
    • 对于代码的注释:
      • 关于 turn函数
      • 关于枚举第一行操作的方式

我好菜,搞了一天,看了题解才知道这题解题的巧妙点在哪,不过好歹是理解了这题的解题思路。。。
题目链接: 95. 费解的开关

解题思路

对于这一题,有三个限制:

  • 对某一开关操作会导致其上下左右四个方向的灯跟随当前位置一起发生亮灭改变
  • 进行完操作后所有的灯必须全亮(题目要求)
  • 按灯的次数要尽量的保持少

对于这几个要求,可以得出几个结论:

  1. 一个位置顶多只会操作一次。因为如果操作两次的话,相当于不操作,必然是不满足最优解。
  2. 一套方案中,操作的顺序无关紧要,这一个略加思索便可得知
  3. 最重要的性质:确定第一行其实就确定了所有的操作
    下面给出一个详细的解答。

为什么确定第一行其实就确定了所有的操作?
当我们确定了第一行,就代表第一行不能动了,而操作第二行会导致第一行的状态发生改变,所以我们得率先操作完第二行,保证第一行的值为我们题目的需求。这样根据第二条结论,不能改变第二行的值了,所以我们只能通过对第三行操作才能改变第二行原本不符合条件的值。同理下面的所有操作其实都在我们确定第一行的操作后确定了,我们接下来只需要判断一下最后一行的值是否是我们需要的值,如果不适合或者总共的操作次数大于6次输出-1,否则再与上一次成功的操作数做对比,输出较小者。

例:(这里借鉴https://blog.csdn.net/qq_41021816/article/details/81810059的示例)
首先我们要枚举第一行灯开关的所有情况,那么如果要改变第一行的灯的状态,那么就只能更改第二行的位于该灯下面的那个开关来改变。

如果我们固定了第一行,那么为了将全部都变成绿色,就必须利用第二行。例如,(1,1)(1,1)是红色,为了让它变成绿色,就必须更改(2,1)(2,1)。为了让(1,4)(1,4)变成绿色,就必须更改(2,4)(2,4)。
更改后图形如下:

那么我们再固定第二行,利用第三行来更改它(就像用第一行来更改第二行一样),就变成了

同理,更改第三行

再更改第四行

这时我们发现,最后还有一个灯是关着的,所以,这说明第一行的灯如果是这样的情况就无法成立
那么就继续枚举第一行的点击方式,再继续按照刚才的方法,判断能否点完即可。

代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;const int N = 6;//g : 用以存储元数据 、
//backup: 用以存储拷贝的数据
char g[N][N], backup[N][N];
//偏移量
int dx[5] = {-1, 0, 1, 0, 0}, dy[5] = {0, 1, 0, -1, 0};
// turn函数用以模拟坐标中 的g[x][y]被按下后的反应
void turn(int x, int y)
{for (int i = 0; i < 5; i ++ ){int a = x + dx[i], b = y + dy[i];if (a < 0 || a >= 5 || b < 0 || b >= 5) continue;   // 在边界外,直接忽略即可g[a][b] ^= 1;}
}int main()
{int T;cin >> T;while (T -- ){//接收第一行 for (int i = 0; i < 5; i ++ ) cin >> g[i];//res为一个理想中的最大值,事实上大于6即可,因为>6就输出-1 int res = 10;//对于每一种第一行的可能操作进行枚举 for (int op = 0; op < 32; op ++ ){//拷贝一份原数组的备份 memcpy(backup, g, sizeof g);int step = 0;//根据第一行的各位置的值对第二行进行操作 for (int i = 0; i < 5; i ++ )if (op >> i & 1) {step ++ ;turn(0, i);}//对剩下的三行进行同样操作 for (int i = 0; i < 4; i ++ )for (int j = 0; j < 5; j ++)if (g[i][j] == '0'){step ++ ;turn(i + 1, j);}//下面的操作是对最后一行的判断,如果全亮说明该选择可行,计入res bool dark = false;for (int i = 0; i < 5; i ++ )if (g[4][i] == '0'){dark = true;break;}//全亮且值比上一次的res小则替代。 if (!dark) res = min(res, step);//拷贝回g ,选择完成。 memcpy(g, backup, sizeof g);} if (res > 6) res = -1;cout << res << endl;}return 0;
}

对于代码的注释:

请在浏览一遍代码以及我的注释之后再看这一部分

关于 turn函数

为了模拟开关按下的操作而设计,我这里定义了两个数组dx和dy,用以分别表示按下(x,y)按键后的x和y的偏移量。
代码第22行采用按位异或1的方式来实现0和1的互相转换。1 ^ 1 =>0 , 0 ^ 1 => 1

关于枚举第一行操作的方式

枚举第一行,我们可以用一个5位的二进制来表示第一行的所有操作,即十进制的op = 0~31来表示5个按键的不同操作,例如op = 00001代表仅对第一个开关进行操作。
代码第47行:op >> i & 1 可以取出op的第i位二进制数值。可以自己用纸笔计算验证

【蓝桥杯备赛笔记 02】费解的开关相关推荐

  1. 蓝桥杯备赛笔记-规律题

    今年大三,开始准备蓝桥杯大赛,在做了第七届以及第六届的题以后,对于蓝桥杯的考点以及考查方式有了一定的了解,这里做一个小结. 蓝桥杯的考察点每年都会考三类题型,第一种是规律题,典型特征是给出一个变化情况 ...

  2. 【背赛笔记 常用写法 模版】Python蓝桥杯备赛笔记记录 【建议收藏!】

    目录 Py常用算法技巧 与c++ stl对应结构 排序 heapq 栈 先进后出队列LifoQueue 优先级队列,每次取最小的一个元素PriorityQueue 双端队列deque ,用在bfs提高 ...

  3. 蓝桥杯备赛--AcWing 668. 游戏时间2

    文章目录 蓝桥杯备赛--AcWing 668. 游戏时间2 lanqiao备赛系列说明 题目 题目描述 输入格式 输出格式 数据范围 下面进行解法思路的详解(这里提供三种思路及解决方案) 一.直接按照 ...

  4. 蓝桥杯备赛(五) 双指针,BFS与图论

    蓝桥杯备赛(五) 双指针,BFS与图论 一.双指针 1.Acwing 1238. 日志统计 小明维护着一个程序员论坛.现在他收集了一份"点赞"日志,日志共有 N 行. 其中每一行的 ...

  5. 【蓝桥杯备赛】历年真题解答+知识点总结

    文章目录 历年真题 算法思维 1. 模拟 1.1日期处理 1.1.1 解法一:win自带的计算器 1.1.2 解法二:Excel+手算 1.1.3 解法三:代码实现 1.2 全排列 1.3 判断回文数 ...

  6. 【蓝桥杯单片机笔记】蓝桥杯备赛资料

    资料目录 资料都是来源自网络,侵删 下载链接 提取码:01xh 蓝桥杯必背 sfr AUXR = 0x8e; sfr P4=0xC0; //矩阵键盘 DS18B20 可添加到main函数里面 void ...

  7. 蓝桥杯备赛 | 官方题库基础练习(含VIP试题)试题+答案(共33题)

    引言 最近在进行蓝桥杯python组的备赛学习,做了官方题库中的基础练习,包括VIP题库,下面是所有试题和AC代码,所有代码都已经通过测试(VIP试题的测试方法见https://blog.csdn.n ...

  8. 蓝桥杯备赛经验分享---如何拿蓝桥国一?

    好久没有正儿八经地写过博客了,今天分享一些自己学习算法的一些经验吧(虽然我很菜 !(OvO)!) step1: 1.你已经有一定的语言基础了,最好对C++/java语法比较熟悉: 2.可以较为熟练地使 ...

  9. 蓝桥杯备赛(网站推荐和一些资料)

    - 首先我唠叨两句,自己对于蓝桥杯的看法 有很多人说,蓝桥杯300报名费会不会太贵了,他们甚至直接称之为"圈钱杯",(可以参加校赛,然后学校付钱)这点我不做过多评论,毕竟事实摆在那 ...

  10. Java在ACM竞赛中的技巧(蓝桥杯备赛总结)

    前言:笔者在这段时间准备蓝桥杯竞赛,由于个人原因选择Java作为语言,刷题中也是不断感到Java有些语法还是不够方便(非常羡慕隔壁C++的STL-),不过有些常见的技巧/方法/模板,也是自己做了些总结 ...

最新文章

  1. Python网络编程:IO多路复用
  2. 【错误记录】TabLayout 升级支持库版本后报错 ( support:design 支持库升级到 28.0.0 后源码发生变更 )
  3. 解决mysqlslap执行命令报错(BEGIN failed--compilation aborted at //bin/mysqlslap line 2098)usr...
  4. tomcat指定配置文件路径方法
  5. php内核介绍及扩展开发指南,4.5. 发布扩展信息
  6. 遍历Map key-value的两种方法、遍历Set方法
  7. 报错:此版本的SQL Server Data Tools与此计算机中安装的数据库运行时组件不兼容...
  8. Counting Bits -leetcode
  9. Android学习之Activity生命周期
  10. angular2-swiper的使用
  11. 宇视智能交通常见的补光灯有哪些?
  12. python 程序员待遇_python程序员待遇如何
  13. Threejs 字体单独发光
  14. 趋势线的拐点突破交易
  15. 使用hutool-poi在未安装Office或wps软件的电脑中生成Excel的xls后缀消失问题
  16. Python简单实现图像融合
  17. 智慧工厂的大脑——APS生产排程系统
  18. 超融合服务器连接虚拟机,H3C UIS 6.5超融合产品新增虚拟机配置指导-5W100
  19. BootLoader——嵌入式系统的引导加载程序
  20. eda技术试卷_EDA技术课程试卷及答案

热门文章

  1. php做后端的优势,【后端开发】php和java的优势
  2. VMware虚拟机中安装Win10系统
  3. 蓝牙协议5.0 第6卷 翻译
  4. 动态规划:走楼梯问题——01
  5. Iterative Reweighted Least Squares
  6. vue开发企业微信应用-开发必读
  7. MPPDB和Hadoop有什么区别
  8. 冯成毅:各类交易者的深度心理剖析
  9. aardio - 伪装进程测试
  10. Pyecharts亚马逊订单可视化