问我们是否可以在6步之内将所有的灯变为亮着的。
首先,每一个位置至多被操作一次。因为操作两次和不操作的效果是一样的,依此类推。
我们枚举出第一行的所有状态,1表示操作,0表示不操作。将第一行操作完之后,第二行的每一台灯是否需要操作其实是一定的。例如对于第i行第j列的灯,如果第i-1行第j列的灯是亮着的,则第i行第j列的灯不能操作,否则必须操作。即只要枚举了第一行的状态,所有位置的灯是否需要操作是固定的。依次操作完五行,我们只需要判断第五行是否全部变亮来判断该方法是否可行。
#include<bits/stdc++.h>
using namespace std;
int n;
char g[6][6];
int dx[5]={-1,0,1,0,0},dy[5]={0,1,0,-1,0};
void tran(int x,int y,int gg[][6]){
for(int i=0;i<5;i++){
int xx=x+dx[i],yy=y+dy[i];
if(xx<0||xx>=5||yy<0||yy>=5)continue;
gg[xx][yy]^=1;
}
}
void solve(){
int ans=100;
for(int i=0;i<5;i++)cin>>g[i];
//枚举第一行状态
for(int i=0;i<32;i++){
int cnt=0;
static int gg[6][6];
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)gg[i][j]=g[i][j]-'0';
for(int j=0;j<5;j++){
if(i>>j&1)tran(0,j,gg),cnt++;
}
for(int j=1;j<5;j++){
for(int k=0;k<5;k++){
if(gg[j-1][k]==0)tran(j,k,gg),cnt++;
}
if(cnt>6)break;
}
bool f=true;
for(int j=0;j<5;j++)
if(gg[4][j]==0){
f=false;
break;
}
if(f)ans=min(ans,cnt);
}
if(ans<=6)cout<<ans<<endl;
else cout<<-1<<endl;
}
int main(){
cin>>n;
while(n--)solve();
return 0;
}