题目链接:点击这里
若该行位置为1,则对下一行的相应位置进行操作,使该行该位置由1变为0。
也就是,如果固定第一行的话,依次类推每次都对下一行进行相应的操作,那么,如果最后一行全为1则成功、有0则失败。
对第一行可以进行的操作有 种,因此,我们可以一一枚举每种操作,按照上面方法固定第一行进行递推,统计出所有成功操作中的最小值。
#include<iostream>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int MOD = 10000007;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const int maxn = 1010;
char a[10][10];
int dx[5] = {0, 1, -1, 0, 0};
int dy[5] = {0, 0, 0, 1, -1};
int ans;
void turn(int x, int y)
{
for(int i = 0; i < 5; ++i)
{
int newx = x + dx[i];
int newy = y + dy[i];
if(newx>=0&&newx<5&&newy>=0&&newy<5)
a[newx][newy] ^= 1;
//'0'(48)^1 = '1'(49)
//'1'(49)^1 = '0'(48)
}
}
int work()
{
for(int k = 0; k < 1<<5; ++k)
{
int res = 0;
char backup[10][10];
memcpy(backup, a, sizeof a);
for(int j = 0; j < 5; ++j)
{
//k的第j位如果是1,是指第一行的这一位应该被切换状态,而和其初始状态无关
if(k >> j & 1) //k的第j位为1
{
res++;
turn(0,j);
}
}
for(int i = 0; i < 4; ++i) //枚举前四行
{
for(int j = 0; j < 5; ++j)
{
if(a[i][j]=='0') //上一行为1,对下一行的相应位置操作
{
res++;
turn(i+1, j);
}
}
}
bool flag = true;
for(int j = 0; j < 5; ++j)
{
if(a[4][j]=='0') //如果最后一行有0,则失败
{
flag = false;
break;
}
}
if(flag) ans = min(ans, res);
memcpy(a, backup, sizeof backup);
}
if(ans>6) ans = -1;
return ans;
}
int main()
{
int t;
cin>>t;
while(t--)
{
for(int i = 0; i < 5; ++i)
for(int j = 0; j < 5; ++j)
cin>>a[i][j];
ans = INF;
cout<<work()<<endl;
}
return 0;
}