Vijos P1197 费解的开关


题目

描述

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

我们用数字“1”表示一盏开着的灯,用数字“0”表示关着的灯。下面这种状态

10111
01101
10111
10000
11011

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

01111
11101
10111
10000
11011

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

01111
11001
11001
10100
11011

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

格式

输入格式

第一行有一个正整数n,代表数据中共有n个待解决的游戏初始状态。
以下若干行数据分为n组,每组数据有5行,每行5个字符。每组数据描述了一个游戏的初始状态。各组数据间用一个空行分隔。
对于30%的数据,n<=5;
对于100%的数据,n<=500。

输出格式

输出数据一共有n行,每行有一个小于等于6的整数,它表示对于输入数据中对应的游戏状态最少需要几步才能使所有灯变亮。
对于某一个游戏初始状态,若6步以内无法使所有灯变亮,请输出“-1”。

样例1

样例输入1

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

样例输出1

3
2
-1

限制

各个测试点1s

来源

Matrix67原创


题解

逆推思想+BFS

首先,我们很容易就会想到通过 BFSBFS / DFSDFS 计算该状态到终状态的步数是否小于6步,然而这个时间复杂度并不是很理想

然后我们又可以想到,从灯全亮的状态进行6次操作,显然对于这些状态一定可以通过逆推的方式在6次操作之内推回全亮的状态

所以,我们只要记录状态以及其步数就可以A掉此题了!!!

这里我用了位运算(懒得开数组和结构体记录了……)


代码

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include <queue>
using namespace std;int t;
int ans[1<<25],q[1<<18]; //第二个数组为了省空间,就开到这么大了,因为操作6次的状态恰好比这个小一点int readln()
{char ch=getchar();while (ch<'0'||ch>'1') ch=getchar();return ch-48;
}int change(int x,int y)
{x^=(1<<y);if (y>=5) x^=(1<<(y-5));if (y<20) x^=(1<<(y+5));if (y%5) x^=(1<<(y-1));if (y%5<4) x^=(1<<(y+1));return x;
}void bfs()
{memset(ans,-1,sizeof(ans));int head=0,tail=1;q[1]=(1<<25)-1;ans[(1<<25)-1]=0;while (head<tail){int x=q[++head];if (ans[x]==6) return;for (int i=0;i<25;i++){int y=change(x,i);if (ans[y]<0) q[++tail]=y,ans[y]=ans[x]+1;}}
}int main()
{scanf("%d",&t);bfs();while (t--){int x=0;for (int i=1;i<=5;i++) for (int j=1;j<=5;j++) x<<=1,x+=readln();printf("%d\n",ans[x]);}return 0;
}

Vijos P1197 费解的开关相关推荐

  1. Vijos 1197 - 费解的开关

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

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

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

  3. AcWing 95. 费解的开关(指数型枚举)

    95. 费解的开关 题意: 给定一个5x5的方格,共25盏灯 每盏灯有开和关两种状态 每次操作一盏灯时,以该灯为中心的十字形状范围的灯都会改变状态 找到用最少的操作步数使所有的灯都亮着,当步数超过6时 ...

  4. AcWing 95. 费解的开关 Python详解

    一.算法思想--递推(详细证明见算法竞赛进阶指南原书) 1)若固定第1行,则方案至多只有1种 2)把第1行的所有情况遍历,先把亮着的灯全部关闭 3)遍历前4行,如果灯是关着的,就把下1行同1列的灯改变 ...

  5. ACW95 费解的开关

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

  6. Acwing:费解的开关

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

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

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

  8. C++费解的开关(递推,位运算)

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

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

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

  10. 【DFS】费解的开关

    L i n k Link Link Joyoi 1266 D e s c r i p t i o n Description Description 你玩过"拉灯"游戏吗?25盏灯 ...

最新文章

  1. Intellij+maven:jar包冲突的解决方法(Hbase和Guava的冲突)
  2. SpringBoot中的自定义路径怎么配置/根目录配置方法
  3. Xshell6连Linux
  4. Java内存泄漏问题
  5. 一个两年Java的面试总结
  6. Python批量拆分Excel文件中已合并的单元格
  7. 【caffe-windows】 caffe-master 之 cifar10 超详细
  8. 某大型银行深化系统技术方案之十六:业务应用层
  9. 绘制Python代码的UML图
  10. Mysql优化(出自官方文档) - 第三篇
  11. FPGA之SDRAM控制器设计(四)
  12. 什么是切片器?如何插入切片器?
  13. 品达通用权限系统(Day 1~Day 2)
  14. uniapp和vue实现打开手机前置摄像头和相机的方法
  15. android crosswalk-webview 取代 webview
  16. 反向迭代器和正向迭代器
  17. 紧随时代的步伐--Java8之Lambda表达式的使用
  18. 微型计算机 介绍 gtx980m,NVIDIA GTX 980M和GTX 1060游戏本谁更值得买?GTX 980M/1060M性能对比评测...
  19. 计算机文化基础008,山东省计算机文化基础选择题
  20. 手机信令数据怎么获得_数据福利|深圳市手机信令数据下载与处理(包括ETC/公交卡/出租车轨迹等)...

热门文章

  1. 全国计算机等级考试 三级网络技术 知识点总结
  2. Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available
  3. Java练手项目:点菜系统
  4. linux vi 表格,关于Linux vi命令 vi命令一览表
  5. 面向对象之多态【向上转型与向下转型】
  6. Windows 10用户档案无法加载的解决方法
  7. “由于这台计算机没有远程桌面客户端访问许可证,远程会话被中断“的解决方案
  8. MySQL中的文本处理函数整理,收藏速查
  9. A. Busiest Computing Nodes
  10. 关于 PHP 的框架 phalcon 学习(一) url 路由过程。