//枚举第一行所有状态,之后再下一行对于第一行每一种状态进行处理,如果第一行对应
//的列是0则必须在下一行按下对应的列,直至循环到第四行位置,这时如果第五行全部为1满足条件
//否则该方案不满足条件
#include<iostream>
#include<cstring>
using namespace std;
const int INF = 100000;
char g[10][10];
int dx[5] = {0,-1,0,1,0},dy[5] = {0,0,1,0,-1};
//实现将对应的上下左右灯状态翻转
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 < 5 && b >= 0 && b < 5)
g[a][b] = '0' + !(g[a][b] - '0');
}
}
//枚举所有方案,返回方案最小步数
int work()
{
int ans = INF;
//用k枚举第一行所有可能的方案,如果k对应二进制位为1则将对应第一行按钮按下,否则不按
for(int k = 0;k < 1 << 5;k++){
int res = 0; //当前步数
char backup[10][10];
memcpy(backup, g, sizeof g);
for(int i = 0;i < 5;i++)
if(k >> i & 1)
turn(0,i),res++;
//对当前行的下一行进行处理,如果当前行对应列为0,下一行对应列需要按下
for(int i = 0;i < 4;i++)
for(int j = 0;j < 5;j++){
if(g[i][j] == '0'){
res++;
turn(i + 1,j);
}
}
bool is_successful = true;
for(int i = 0;i < 5;i++)
if(g[4][i] == '0'){
is_successful = false;
break;
}
if(is_successful) ans = min(res,ans);
memcpy(g, backup, sizeof backup);
}
if(ans > 6) return -1;
return ans;
}
int main()
{
int n;
cin >> n;
while(n--){
for(int i = 0;i < 5;i++)
for(int j = 0;j < 5;j++)
cin >> g[i][j];
cout << work() << endl;
}
return 0;
}
02-15
03-14
03-30
08-31