(题面来自ACwing)

你玩过“拉灯”游戏吗?25盏灯排成一个5x5的方形。每一个灯都有一个开关,游戏者可以改变它的状态。每一步,游戏者可以改变某一个灯的状态。游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也要相应地改变其状态。

我们用数字“1”表示一盏开着的灯,用数字“0”表示关着的灯。

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

输入格式

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

以下若干行数据分为n组,每组数据有5行,每行5个字符。每组数据描述了一个游戏的初始状态。各组数据间用一个空行分隔。

输出格式

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

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

  题意的本质是:求解把一个5 * 5的01方阵通过上述操作变换成为仅由1构成的方阵的最小步数。如果单纯每次枚举改变的点来爆搜,状态空间的大小不能承受,显然行不通。

  实际上,题中所给的变换具有两个很重要的性质。首先,每个点最多被变换一次,因为重复的操作是无效的;第二,相同操作的不同顺序不会影响最终结果,因为累计在每个位置上的效果都一样。

  从这两点出发,我们发现可以枚举部分变换来递推所有的操作。具体来说,考虑逐行进行变换,那么当前行i上面所有行所进行的变换已经确定了;如果第i-1行上的第k个位置上有0,那么只能通过改变第i行的第k个位置使第i-1行合法,这是解答本题的关键。因此,我们可以二进制枚举在第一行进行的2^5 = 32种变换,然后依次递推第2~5行的操作。最后检查第五行是否全部为1,若第五行状态合法就用当前的步数更新答案即可。

  从这个题吸取的教训是,要慎用语句"ios::sync_with_stdio(0)",因为这个指令取消了cin和C标准输入输出的兼容性,一旦手滑同时使用cin和getchar、scanf等C库读入函数就会发生错误。这句话最好在读入字符串时再考虑适用,平时应该手写快读来避免悲剧。

代码:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5. #include <ctime>
  6. using namespace std;
  7. const int inf = 0x3f3f3f3f;
  8. int sw[10][10], tmp[10][10], cnt, ans;
  9. int addx[5] = {0, 0, 0, -1, 1}, addy[5] = {0, 1, -1, 0, 0};
  10. void change(int x, int y, int a[10][10]) {
  11. int tx, ty;
  12. for (int i = 0; i < 5; ++i) {
  13. tx = x + addx[i], ty = y + addy[i];
  14. if (a[tx][ty] == -1) continue;
  15. a[tx][ty] = !a[tx][ty];
  16. }
  17. ++cnt;
  18. }
  19. void init(int x) {
  20. memcpy(tmp, sw, sizeof(tmp));
  21. for (int i = 1; i <= 5; ++i)
  22. if (x >> (i - 1) & 1)
  23. change(1, i, tmp);
  24. }
  25. int main() {
  26. int T;
  27. cin >> T;
  28. while (T--) {
  29. ans = inf;
  30. memset(sw, -1, sizeof(sw));
  31. char ch;
  32. for (int i = 1; i <= 5; ++i) {
  33. while (!isdigit(ch))
  34. ch = getchar();
  35. for (int j = 1; j <= 5; ++j)
  36. sw[i][j] = ch - 48, ch = getchar();
  37. }
  38. /*      for (int i = 1; i <= 5; ++i) {
  39. for (int j = 1; j <= 5; ++j)
  40. cout << sw[i][j] << " ";
  41. cout << endl;
  42. }*/
  43. for (int x = 0; x < 32; ++x) {
  44. cnt = 0;
  45. init(x);
  46. for (int i = 2; i <= 5; ++i)
  47. for (int j = 1; j <= 5; ++j)
  48. if (!tmp[i - 1][j])
  49. change(i, j, tmp);
  50. for (int i = 1; i <= 5; ++i)
  51. if (!tmp[5][i]) cnt = inf;
  52. ans = min(ans, cnt);
  53. }
  54. if (ans <= 6)
  55. cout << ans << endl;
  56. else puts("-1");
  57. }
  58. return 0;
  59. }

转载于:https://www.cnblogs.com/TY02/p/11253373.html

【ACwing 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. 费解的开关

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

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

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

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

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

  7. Acwing:费解的开关

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

  8. 【结论】【dfs】费解的开关(joyoi-tyvj 1266)

    费解的开关 joyoi-tyvj 1266 题目大意: 有5*5的一个图,每个点的数值是1或0,如果将一个点的数值取反,那这个点上下左右的点都会取反,现在问你将所有点都变为1最少要多少步,如果步数大于 ...

  9. Windows枚举搜索远程蓝牙设备

    主要使用微软自带的蓝牙API,注意使用的蓝牙适配器应当使用的是微软自带的蓝牙驱动(可以通过设备和打印机界面添加远程蓝牙设备即表示可以使用windows蓝牙api,此时安装的蓝牙设备会在设备管理器中显示 ...

  10. 费解的开关(位运算+递推)

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

最新文章

  1. 面试必问的分布式相关内容(未完待续)
  2. mobilenet精髓全力解析,全力迁移到别的网络
  3. POJ1456贪心(set或者并查集区间合并)
  4. grid - 使用相同的名称命名网格线和设置网格项目位置
  5. golang中的消息认证
  6. WINCE下如何设置/删除/查询这些环境变量
  7. python中遍历结构可以是哪些数据类型_全!Python基础之原生数据类型、判断和循环、函数和文件操作合集...
  8. 2017蓝桥杯省赛---java---A---1(迷宫)
  9. 多智能体强化学习算法【三】【QMIX、MADDPG、MAPPO】
  10. 【怎样防止黑客入侵电脑 九个设置让电脑远离黑客】
  11. 刚安装3dsmax2020无法保存文件或注册机无法patch
  12. 软件开发过程中的环境简介
  13. C#理论 —— 文件操作、委托和事件
  14. linux卡住重启_linux df -h 命令卡住 解决方法
  15. u盘插电脑计算机卡了,电脑插入U盘就卡顿?3个原因你需要了解一下
  16. python实现实现快速输入无法粘贴的内容
  17. 【前端开发遇到到的问题2】文字下方加下划线
  18. 如何用cmd命令进入mysql
  19. 算法实验题 1.4 画展活动
  20. 揭秘卫星互联网!6G关键技术,国内行业雏形初现

热门文章

  1. php 安装pdo odbc,php如何安装pdo odbc扩展
  2. 【渝粤教育】国家开放大学2018年秋季 0363-21T市场调查与预测 参考试题
  3. [渝粤教育] 中国地质大学 计算机图形学(新) 复习题 (2)
  4. 【渝粤题库】陕西师范大学800009 环境变迁
  5. java面向对象之封装
  6. 力扣——查找常用字符
  7. Webpack 中 css import 使用 alias 相对路径
  8. 相机拍照功能之权限和Android版本问题
  9. Python深入理解yield
  10. [转]利用C#操作配置文件