【ACwing 95】费解的开关——枚举 + 搜索
(题面来自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库读入函数就会发生错误。这句话最好在读入字符串时再考虑适用,平时应该手写快读来避免悲剧。
代码:
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- #include <ctime>
- using namespace std;
- const int inf = 0x3f3f3f3f;
- int sw[10][10], tmp[10][10], cnt, ans;
- int addx[5] = {0, 0, 0, -1, 1}, addy[5] = {0, 1, -1, 0, 0};
- void change(int x, int y, int a[10][10]) {
- int tx, ty;
- for (int i = 0; i < 5; ++i) {
- tx = x + addx[i], ty = y + addy[i];
- if (a[tx][ty] == -1) continue;
- a[tx][ty] = !a[tx][ty];
- }
- ++cnt;
- }
- void init(int x) {
- memcpy(tmp, sw, sizeof(tmp));
- for (int i = 1; i <= 5; ++i)
- if (x >> (i - 1) & 1)
- change(1, i, tmp);
- }
- int main() {
- int T;
- cin >> T;
- while (T--) {
- ans = inf;
- memset(sw, -1, sizeof(sw));
- char ch;
- for (int i = 1; i <= 5; ++i) {
- while (!isdigit(ch))
- ch = getchar();
- for (int j = 1; j <= 5; ++j)
- sw[i][j] = ch - 48, ch = getchar();
- }
- /* for (int i = 1; i <= 5; ++i) {
- for (int j = 1; j <= 5; ++j)
- cout << sw[i][j] << " ";
- cout << endl;
- }*/
- for (int x = 0; x < 32; ++x) {
- cnt = 0;
- init(x);
- for (int i = 2; i <= 5; ++i)
- for (int j = 1; j <= 5; ++j)
- if (!tmp[i - 1][j])
- change(i, j, tmp);
- for (int i = 1; i <= 5; ++i)
- if (!tmp[5][i]) cnt = inf;
- ans = min(ans, cnt);
- }
- if (ans <= 6)
- cout << ans << endl;
- else puts("-1");
- }
- return 0;
- }
【ACwing 95】费解的开关——枚举 + 搜索的更多相关文章
- AcWing 95 费解的开关
目录 前言 题目链接 思路 代码 前言 博客咕咕咕了好久了,是时候写一下了 题目链接 AcWing 95 费解的开关 思路 首先可以看出 1.每一个位置顶多只会操作一次.因为如果操作两次的话,相当于不 ...
- ACWING 95 费解的开关 解题记录
你玩过“拉灯”游戏吗?25盏灯排成一个5x5的方形.每一个灯都有一个开关,游戏者可以改变它的状态.每一步,游戏者可以改变某一个灯的状态.游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也 ...
- CH0201 费解的开关 枚举
正解:枚举 解题报告: 入门傻逼题,思维难度不高代码量极小,非常适合上手 然后傻逼的我第二次看这道题的时候依然没想到解法:D 没有办法,就想着写个笔记好歹记录一下以后多复习几次就记着了趴qwq 就是, ...
- AcWing95. 费解的开关 枚举+位运算
这道题的确比较难想,首先我们知道图比较小,有可能是枚举,那么该如何枚举呢??? 你可以发现,我们只要把第一排定了,并且保证第一排不准动,那么答案就定了 也就是说,我们首先用二进制枚举,枚举第一行需要翻 ...
- ACAG 0x02-4 费解的开关
ACAG 0x02-4 费解的开关 对于这道题,我们不难发现如下性质: 每个位置之多被点击一次: 点击的先后顺序不影响结果: 若确定了第$1$行,则接下来可能的点击方案就只有$1$种.具体原因是:当第 ...
- TyvjP1266 费解的开关
P1266 费解的开关 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 你玩过“拉灯”游戏吗?25盏灯排成一个5x5的方形.每一个灯都有一个开关,游戏 ...
- hdu4431 Mahjong 枚举搜索。。
japanese麻将什么玩意..都没有豪华七对... 没什么难的 就是枚举搜索了 分三种类型的胡牌 f1是七对 f2是十三幺 f3是普通的胡牌 就先找一对 再找三个三个的 就是一直超时..在峰峰的指导 ...
- AcWing 92. 递归实现指数型枚举
题目链接:https://www.acwing.com/problem/content/description/94/ 题意:从 n 个数中选取数字,输出所有的选取可能 idea:枚举所有取数可能,就 ...
- HDU 4900 NO ACM NO LIFE(概率+枚举+搜索)(2014 Multi-University Training Contest 4)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4900 Problem Description There is an old country and ...
随机推荐
- JavaScript实现基于数组的栈
class StackArray { constructor() { this.items = []; } push(element) { this.items.push( ...
- STM32入门系列-GPIO工作模式及LED电路原理
GPIO工作模式 由于GPIO内部的结构关系,决定了GPIO可配置成以下几种模式. 输入模式 在输入模式时,施密特触发器打开,输出被禁止.可通过输入数据寄存器GPIOx_IDR读取I/O状态.输入模式 ...
- SpringBoot整合Logback日志框架配置全解析
目录 本篇要点 一.Logback日志框架介绍 二.SpringBoot与Logback 1.默认日志格式 2.控制台输出 3.文件输出 4.日志级别 5.日志组 6.自定义log配置 三.logba ...
- [Luogu P4173]残缺的字符串 ( 数论 FFT)
题面 传送门:洛咕 Solution 这题我写得脑壳疼,我好菜啊 好吧,我们来说正题. 这题.....emmmmmmm 显然KMP类的字符串神仙算法在这里没法用了. 那咋搞啊(或者说这题和数学有半毛钱 ...
- [CF160D]Edges in MST (最小生成树+LCA+差分)
待填坑 Code //CF160D Edges in MST //Apr,4th,2018 //树上差分+LCA+MST #include<cstdio> #include<iost ...
- 不停机不更新代码线上调试BUG的工具
如果你有以下痛点,请你查看本文章: 1.我改的代码为什么没有执行到?难道是我没 commit?分支搞错了? 2.遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗? 3.线上遇到某个用户的 ...
- POI做题记录
嘿嘿,偷学一波! 由于博主做的题比较少,所以没按年份整理,直接按照做题时间放上来了. 2020年9月20日 [POI2013]LUK-Triumphal arch 给你一颗\(n\)个点的树(\(n\ ...
- 在嵌入式设备中实现webrtc的第三种方式③
本系列的最后一篇,讲解收发音视频数据. 贴出最终效果: 其实很简单,直接调用writeFrame即可,如下图: 当然,这是部分代码,完整代码在下面,展开可见: 1 #include "com ...
- 4、Django之视图层
一 视图函数 视图函数,简称视图,属于Django的视图层,默认定义在views.py文件中,是用来处理web请求信息以及返回响应信息的函数,所以研究视图函数只需熟练掌握两个对象即可:请求对象(Htt ...
- 腾讯云--腾讯云sdk-实现脚本修改腾讯云负载均衡权重
一.请确认你的当前python环境为python 2.x 获取 python 版本的方法 (linux shell) # python -v python 2.7.11 二.CLB SDK下载与配置 ...