ac代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
/*
1.每一行按的顺序是任意的
2.每个格子最多按一次(按两次相当没按)
3.按过第一行后,下一行能按的只有上一行是暗的的正下方;
若上一行是亮的,正下方一行不能按
枚举第一行操作
pow(2,5)-1 = 31 所以i(1~32) 看从右往左数第k位是否是1 ( i<<k & 1 )
按完后状态改变 上下左右偏移量分别(-1,0) (+1,0) (0,-1) (0,+1)
*/
const int N = 6;
char g[N][N], backup[N][N];
int dx[5] = {-1, 0, 1, 0, 0}, dy[5] = {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 >= 5|| b < 0 || b >= 5) continue;
g[a][b] ^= 1; //'0' '1' 的ASC码 98 99
}
}
int main()
{
IOS;
int T;
cin>>T;
while(T--)
{
for(int i = 0; i < 5; i++) cin >> g[i];
int res = 10;
for(int op = 0; op < 32; op++)
{
memcpy(backup, g, sizeof g);
int step = 0;
//对第一行进行操作
for(int i = 0; i < 5; i++)
if(op >> i & 1) //表示进行操作了
{
step ++ ;
turn(0,i);
}
//对除第一行外的行进行操作
for(int i = 0; i < 4; i++) //上一行决定下一行,从第0行到第4行 决定 第1行到第5行
for(int j = 0; j < 5; j++)
if(g[i][j] == '0') //表示上一行是灭的,则下一行一定按一下
{
step ++;
turn(i + 1,j); //下一行按后周围状态改变
}
//判断最后一行有无暗的,最后一行无法进行操作了,如果是暗的,那就无解
bool dark = false;
for(int i = 0; i < 5; i++)
if(g[4][i] == '0')
{
dark = true;
break;
}
if(!dark) res = min(res, step);
memcpy(g, backup, sizeof g);
}
if(res > 6) res = -1;
cout << res << endl;
}
return 0;
}