本文共 1874 字,大约阅读时间需要 6 分钟。
你玩过“拉灯”游戏吗?25盏灯排成一个5x5的方形。每一个灯都有一个开关,游戏者可以改变它的状态。每一步,游戏者可以改变某一个灯的状态。游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也要相应地改变其状态。
我们用数字“1”表示一盏开着的灯,用数字“0”表示关着的灯。下面这种状态
1011101101101111000011011
在改变了最左上角的灯的状态后将变成:
0111111101101111000011011
再改变它正中间的灯后状态将变成:
0111111001110011010011011
给定一些游戏的初始状态,编写程序判断游戏者是否可能在6步以内使所有的灯都变亮。
输入格式
第一行输入正整数n,代表数据中共有n个待解决的游戏初始状态。以下若干行数据分为n组,每组数据有5行,每行5个字符。每组数据描述了一个游戏的初始状态。各组数据间用一个空行分隔。
输出格式
一共输出n行数据,每行有一个小于等于6的整数,它表示对于输入数据中对应的游戏状态最少需要几步才能使所有灯变亮。对于某一个游戏初始状态,若6步以内无法使所有灯变亮,则输出“-1”。
数据范围
0<n≤500 输入样例:3001110101110001110101110011101111011111011111111110111111111111111111111111
输出样例:
32-1
思路
这道题确实很有难度,y总给出了一个思路,将第一行锁死,然后从第一行开始从第一行到第四行只要遇到0就改变下一行的灯,也就是说第一行的位置确定,得到的灯泡亮度图也是确定的,不亮的灯只会出现在最后一行,因为前四行都被我们改变全部都是亮的,第一行有25=32中方案,我们依次枚举这些方案,然后判断一共需要多少步并且是否可以达到目标状态,题目中说最少在6步以内并且全部都是开的。主要思想
全排列代码如下
#include#include #include using namespace std;const int N=10;char g[N][N],bg[N][N];int dx[5]={ 0,0,0,1,-1},dy[5]={ 1,-1,0,0,0};void turn(int x,int y){ for(int i=0;i<5;i++) { int tx=x+dx[i]; int ty=y+dy[i]; if(tx>=0&&ty>=0&&tx<5&&ty<5) { bg[tx][ty]='1'-bg[tx][ty]+'0'; } }}int main(void){ int n; scanf("%d",&n); while(n--) { for(int i=0;i<5;i++) scanf("%s",g[i]); int res=10; for(int i=0;i<32;i++) { memcpy(bg,g,sizeof g); int cnt=0; for(int j=0;j<5;j++) { if(i>>j&1) turn(0,j),cnt++; } for(int j=0;j<4;j++) { for(int p=0;p<5;p++) { if(bg[j][p]=='0') turn(j+1,p),cnt++; } } bool flag=true; for(int j=0;j<5;j++) if(bg[4][j]=='0') flag=false; if(flag&&cnt
转载地址:http://phkpz.baihongyu.com/