文章目录

  • 题目
  • 题解
  • 代码

题目来源 AcWing。

题目

你玩过“拉灯”游戏吗?

252525 盏灯排成一个 5×55 \times 55×5 的方形。

每一个灯都有一个开关,游戏者可以改变它的状态。

每一步,游戏者可以改变某一个灯的状态。

游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也要相应地改变其状态。

我们用数字 111 表示一盏开着的灯,用数字 000 表示关着的灯。

下面这种状态

10111
01101
10111
10000
11011

在改变了最左上角的灯的状态后将变成:

01111
11101
10111
10000
11011

再改变它正中间的灯后状态将变成:

01111
11001
11001
10100
11011

给定一些游戏的初始状态,编写程序判断游戏者是否可能在 666 步以内使所有的灯都变亮。

输入格式

第一行输入正整数 nnn,代表数据中共有 nnn 个待解决的游戏初始状态。

以下若干行数据分为 nnn 组,每组数据有 555 行,每行 555 个字符。

每组数据描述了一个游戏的初始状态。

各组数据间用一个空行分隔。

输出格式

一共输出 nnn 行数据,每行有一个小于等于 666 的整数,它表示对于输入数据中对应的游戏状态最少需要几步才能使所有灯变亮。

对于某一个游戏初始状态,若 666 步以内无法使所有灯变亮,则输出 −1-1−1。

数据范围

  • 0≤n≤5000 \le n \le 5000≤n≤500

输入样例:

3
00111
01011
10001
11010
1110011101
11101
11110
11111
1111101111
11111
11111
11111
11111

输出样例:

3
2
-1

题解

首先有三点很重要的性质需要说明:

  • 如果按哪些灯确定了,那么按这些灯的顺序不重要,无论什么顺序,结果都是相同的
  • 我们没有必要按一盏灯两次及以上,因为,按两次,相当于没按,按三次,相当于按两次+一次(也就是一次)

因此:

  • 因为按灯的顺序不重要,我们可以先把第一行的灯都按了
  • 我们发现,第一行想按的灯都按过之后,如果想要让第一行全亮,那么我第二行只能有一种按法,就是按第一行不亮的灯的下面的灯(下面是例子)
第一行状态 10011 (1代表亮的灯)
第二行动作 01100 (1代表按按钮)

那么,我们怎么保证第二行全亮呢?只能用第三行来解决!

那么,我们怎么保证最后一行(第五行)全亮呢?没法保证!

我们发现,如果第一行按法确定了,那么接下来二三四五行的按法和能不能全亮就确定了。

因此,对于任意一种输入状态,我们把第一行 32 种按法全部遍历一遍,看看哪些可以全亮(通过检测第五行状态),这些全亮的种有没有操作次数小于等于 6 的。有的话,就返回这个操作数,否则就返回 -1 呗。

代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;const int N = 5 + 5;   // 加上 5 更保险
// 注意接收时用字符串更方便,因为输入流每行没有空格
char g[N][N];  // 记录灯目前的情况// 上右下左中
int dx[5] = {0, 1, 0, -1, 0};
int dy[5] = {1, 0, -1, 0, 0};// 按第 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 (0 <= a && a < 5 && 0 <= b && b < 5)g[a][b] = g[a][b] == '1' ? '0': '1';}
}int work()
{int ans = 2e9;// 第一层循环,把所有第一行按的情况都遍历// k 是被压缩了的状态,最小 0b00000 代表都不按,// 最大 0b11111 代表都按// 备份,因为下面的操作会改变 gchar backup[N][N];memcpy(backup, g, sizeof g);for (int k = 0; k < (1 << 5); ++ k){// 确保我们的 g 是输入的 gmemcpy(g, backup, sizeof backup);// 当第一行为 k 时,总操作次数是..int res = 0;  // 用 res 来记录// 执行 k (根据 k 把第一行按了)for (int j = 0; j < 5; ++ j){if (k >> j & 1){res ++;turn(0, j);}}// 第一行确定了,第二行就确定了// 因为只有合理操作第二行// 才能把第一行全部点亮// 以此类推,第二行定了后,第三行就被第二行决定了for (int i = 0; i < 4; ++ i){for (int j = 0; j < 5; ++ j){if (g[i][j] == '0'){res ++;turn(i + 1, j);}}}// 上面的操作一定能保证前 4 行全亮// 但是第 5 行不一定全亮,第 5 行全亮,才是真正有效的操作bool success = true;for (int j = 0; j < 5; ++ j){if (g[4][j] == '0'){success = false;break;}}// 如果是有效的操作,咱看看一共按了几次开关if (success) ans = min(res, ans);}// 根据题意返回输出值if (ans > 6) return -1;return ans;
}int main()
{int n;cin >> n;while (n -- ){for (int i = 0; i < 5; ++ i) cin >> g[i];printf("%d\n", work());}
}

递推算法题:令人费解的开关『拉灯』相关推荐

  1. 递推算法题:王小二刀工之王小二切大饼

    题目描述:王小二自夸活好,刀工不错,有人给他画了个大饼,问他:"切100刀能把大饼分成多少块?",切法是让每两条线都有交点. 定义n为切的刀数 定义q(n)为n刀能分成的块数 找规 ...

  2. 算法竞赛宝典-递推算法

    算法竞赛宝典-递推算法 Problem A [递推]挖地雷 待更新 问题 B: [递推]偶数3的个数 时间限制: 1 Sec 内存限制: 64 MB 题目描述 "报告,我军已探出地雷阵中所有 ...

  3. 扩展欧几里得算法_扩展欧几里得递推算法

    欧几里得算法 表示 整数 a 与 b 的最大公约数. 若 t = a % b, 则 证明略. 递推版 gcd 算法 gcd 接受变量元组 (a, b) 作为输入,输出最大公约数 (r). 我们很难直接 ...

  4. 基础算法 —— 递推算法

    [概述] 递推算法:通过已知条件,利用相邻的数据项间的关系(即:递推关系),得出中间推论,直至得到结果的算法. 递推关系:给定一个数的序列H0,H1,-,Hn,若存在整数N0,使当n>N0时,可 ...

  5. 算法设计与分析第一章递推算法

    算法设计与分析 第一章 递推算法 1.概述 在**已知条件**和**所求问题**之间总存在着某种相互联系的关系,如果可以找到前后过程之间的数量关系(即递推式),那么,从**问题出发逐步推到已知条件** ...

  6. java穷举密码_穷举算法和递推算法(Java)

    穷举算法 概念: 最简单算法,依赖计算机的强大计算能力穷尽每一种可能的情况.穷举算法效率不高,但是适合一些没有明显规律可循的场合. 思想: 在使用穷举算法时,需要明确问题答案的范围,这样才可能在指定范 ...

  7. 2022蓝桥杯B组—积木画——递推算法

    积木画 题目描述 小明最近迷上了积木画,有这么两种类型的积木,分别为 III 型(大小为 222 个单位面积)和 LLL 型(大小为 333 个单位面积): 同时,小明有一块面积大小为 2×N2×N2 ...

  8. 计算机控制求输出递推计算题,2020计算思维复习

    只是供自己复习使用,无参考价值.本人无法对以下内容的准确性做保证,大家看看就好. 如发现错误,希望大家多多指正. 第一章: 1.什么是计算思维(书P17) PPT上的: "计算思维就是运用计 ...

  9. 求逆元的两种方法+求逆元的O(n)递推算法

    到国庆假期都是复习阶段..所以把一些东西整理重温一下. gcd(a,p)=1,ax≡1(%p),则x为a的逆元.注意前提:gcd(a,p)=1; 方法一:拓展欧几里得 gcd(a,p)=1,ax≡1( ...

最新文章

  1. MOD函数语法和参数
  2. python 打开当前目录的txt文件-Python - 读取其他文件夹/目录中的文本文件
  3. python导入mongo数据库文件
  4. 转: HTTP 错误 401.1 - 未经授权:访问由于凭据无效被拒绝的另类解决方案
  5. HDOJ1014 Uniform Generator
  6. spring之@value设置默认值
  7. 蓝桥杯 BASIC-3 基础练习 字母图形
  8. 士兵杀敌 三 --- O( 1 ) 的时间复杂度 .
  9. win7 java下载_Windows7系统下JAVA运行环境下载、安装和设置(第二次更新:2012年03月14日)...
  10. 千峰JAVA逆战班Day34
  11. 成为UiBot Store推广员,解锁全新赚钱方式
  12. 为何excel中数据无法计算机,造成Excel表格打不开的几种原因及解决办法
  13. 国考省考行测:问题型材料主旨分析,有问题有对策,主旨是对策,有问题无对策,要合理引申对策
  14. HDMI设计1--HDMI 1.4b SPEC的阅读个人总结
  15. 单片机的组成、工作原理、分类、特点以及发展趋势
  16. ECS的简单入门(一):概念
  17. 孤岛危机 教程:使用Voxel技术创建地形
  18. signature=e7a4f21fa0bd38abc7e1a2451a8b7b26,Win10 14328起“迅雷7.9、迅雷极速版”崩溃修正补丁...
  19. ip伪装软件对游戏多开有什么用?
  20. EBS应收自动开票错误:AR_RAXTRX-1783

热门文章

  1. Linux中 Vi的使用
  2. 测量不确定度matlab,基于MATLAB用蒙特卡洛法评估测量不确定度简介,目录书摘
  3. 【Python-2.7】多种方式删除列表元素
  4. 移动端和PC端弹出遮罩层后,页面禁止滚动的解决方法及探究
  5. MISCONF Redis配置为保存RDB快照
  6. 是否有唯一的Android设备ID?
  7. glassfish 是oracle的,GlassFish“百天”小版本 彰显Oracle的大功力
  8. win7旗舰版系统如何重装系统win10
  9. win11桌面图标模糊怎么办 windows11桌面图标模糊的解决方法
  10. ros开发增加clion常用模板及初始化配置(四)