95. 费解的开关
- 每个位置至多只会被点击一次
- 若固定了第一行,则满足题意的点击方案至多只有一种。原因:当第i行某一位为1时,若前i行已被固定,只能点击第i+1行该位置上的数字才能使第i行的这一位变成0,从上到下使用归纳法可得上述结论。
- 点击的先后顺序不影响最终结果。
于是,我们不妨先考虑第一行如何点击。在枚举第一行的点击方案后,就可以认为第一行固定不动,在考虑2 ~ 5行如何点击。而按照上述性质2,此时第2 ~ 5行的点击方案是确定的。
若到达第n行是不全为1,说明这种点击方式不合法。在所有合法的点击方式中取点击次数最少的就是答案。
const int N=5;
char g[N][N];
char tmp[N][N];
void change(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)
tmp[a][b]='0'+(tmp[a][b]-'0')^1;
}
}
int main()
{
int T;
cin>>T;
while(T--)
{
for(int i=0;i<5;i++) scanf("%s",g[i]);
int res=INF;
for(int s=0;s<(1<<5);s++)
{
memcpy(tmp,g,sizeof g);
int step=0;
for(int i=0;i<5;i++)
if(s >>i & 1)
{
step++;
change(0,i);
}
for(int i=1;i<5;i++)
for(int j=0;j<5;j++)
if(tmp[i-1][j] == '0')
{
change(i,j);
step++;
}
bool ok=true;
for(int i=0;i<5;i++)
if(tmp[4][i] == '0')
{
ok=false;
break;
}
if(ok) res=min(res,step);
}
if(res > 6) res=-1;
cout<<res<<endl;
}
//system("pause");
return 0;
}