-
按法与顺序无关
-
每个各自最多按一次
-
枚举第一行的操作
-
每一行开关的操作由上一行灯的亮灭唯一确定
-
枚举第一行的状态
利用位运算 -
从第二行开始由上一行灯的亮灭决定本行的开关操作,当要执行第h行时,前n-1行一定全亮,只要特判最后一行是否全亮即可
在做题时要注意数据范围!飞行员问题可以直接枚举216到225
定义偏移量
#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] ^= 1;
}
}
}
int work()
{
int ans = INF;
for(int k = 0; k < 1 << 5; k++)
{
int res=0;
char backup[10][10];
memcpy(backup,g,sizeof g);
for(int j=0; j<5; j++)
if(k >> j & 1)
{
res++;
turn(0,j);
}
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 j=0; j<5; j++)
if(g[4][j]=='0')
{
is_successful = false;
break;
}
if(is_successful) ans = min(ans,res);
memcpy(g, backup, sizeof g);
}
if(ans > 6) ans = -1;
return ans;
}
int main()
{
int T;
cin >> T;
while(T--)
{
for(int i = 0; i<5; i++) cin >> g[i];
cout << work() << endl;
}
return 0;
}