费解的开关
题意描述
你玩过“拉灯”游戏吗?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个字符。每组数据描述了一个游戏的初始状态。各组数据间用一个空行分隔。
输出格式 一共输出n行数据,每行有一个小于等于6的整数,它表示对于输入数据中对应的游戏状态最少需要几步才能使所有灯变亮。 对于某一个游戏初始状态,若6步以内无法使所有灯变亮,则输出“-1”。
数据范围 0<n≤500
输入样例: 3 00111 01011 10001 11010 11100
11101 11101 11110 11111 11111
01111 11111 11111 11111 11111
输出样例:
3 2 -1
思路
我们可以发现,每一行的状态是由它的上一行来决定。所以我们需要做的是,固定它的第一行,然后枚举其余的四行的状态来进行操作。当枚举完以后,还需要对最后一行灯的状态进行检查。由于第一行也是可以操作的,每一个灯都有按或者不按两个选项,所以我们要枚举所有第一行能够进行的操作,然后开始递推,找出一个最佳的答案即可。
AC代码
#include<iostream>
#include<cstring>
using namespace std;
const int N=6;
char g[N][N],backup[N][N];
int n;
void turn(int x,int y){
int dx[5]={-1,0,1,0,0},dy[5]={0,-1,0,1,0};
for(int i=0;i<5;i++){
int gx=x+dx[i],gy=y+dy[i];
if(gx<0&&gy<0&&gx>=5&&gy>=5) continue;
g[gx][gy]^=1;
}
}
int main(){
cin>>n;
while(n--){
int res=7;
for(int i=0;i<5;i++) cin>>g[i];
for(int op=0;op<32;op++){
int step=0;
memcpy(backup,g,sizeof g);
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'){
turn(i+1,j);
step++;
}
}
}
bool dark=false;
for(int i=0;i<5;i++){
if(g[4][i]=='0'){
dark=true;
break;
}
}
if(!dark) res=min(res,step);
memcpy(g,backup,sizeof backup);
}
if(res>6) cout<<"-1"<<endl;
else cout<<res<<endl;
}
}
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 前端科普系列(5):ESLint - 守住优雅的护城河
- 图的储存方式,链式前向星最简单实现方式 (边集数组)
- 技术前刊:PostgreSQL12 COPY和bulkloading提升
- 疯子的算法总结(八) 最短路算法+模板
- POJ - 2387 Til the Cows Come Home (最短路入门)
- POJ - 3074 Sudoku (搜索)剪枝+位运算优化
- C语言rand随机函数问题
- HDU - 1253 胜利大逃亡(搜索)
- Android7.0版本影响开发的改进分析
- POJ - 2251 Dungeon Master(搜索)
- An Overview of PostgreSQL & MySQL Cross Replication
- POJ - 1321 棋盘问题
- CREATE TABLE ... WITH storage_parameter [= value] [, ... ]
- Windows窗口模板
- TabLayout关联ViewPager后不显示文字的解决方法