带注释,不懂的地方随时提问哦
//每一行开关的操作,完全被前一行灯亮灭的情况所决定。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 6;
char g[N][N], backup[N][N];
int dx[N] = {-1, 0, 1, 0, 0}, dy[N] = {0, 1, 0, -1, 0}; //按一下,对五个位置改变的坐标。
void turn(int x, int y) //用来改变灯的暗亮。
{
for(int i = 0; i < 5; i++)
{
int a = x + dx[i], b = y + dy[i];
if(a < 0 || a > 4 || b < 0 || b > 4) continue; //判断边界,超出边界则不进行改变
g[a][b] ^= 1; //将1变0,0变1
}
}
int main()
{
int n;
scanf("%d", &n);
while(n--)
{
for(int i = 0; i < 5; i++) scanf("%s", g[i]);
int res = 7; //用来存放最小步骤
for(int op = 0; op < 32; op++) //第一行按与不按一共32种情况
{
memcpy(backup, g, sizeof g); //复制g数组给backup
int step = 0; //步骤从0开始
for(int i = 0; i < 5; i++) //1表示按,0表示不按
if(op >> i & 1) //查看每一位,如果是1,就表示按下,如果是0,表示没按
{
step++;
turn(0, i);
}
for(int i = 0; i < 4; i++) //第234行,根据上一行做出改变。
for(int j = 0; j < 5; j++)
if(g[i][j] == '0')
{
turn(i + 1, j);
step++;
}
bool dark = false; //用来判断最后一行
for(int j = 0; j < 5; j++) //判断最后一行是否有灭的灯
if(g[4][j] == '0')
{
dark = true;
break;
}
if(!dark) res = min(res, step); //如果最后一行的灯都亮着,则存放最小步骤
memcpy(g, backup, sizeof g);
}
if(res > 6) printf("-1\n");
else printf("%d\n", res);
}
return 0;
}