用深搜做该题时,对每一个点都遍历一遍会超时
所以应该对其优化
先来看例子
1 0 1 1 1
0 1 1 0 1
1 0 1 1 1
1 0 0 0 0
1 1 0 1 1
先看第一行,若我们想修改第一行的值,只需要修改位于它下面的值

1 1 1 1 1
1 0 0 0 1
1 1 1 1 1
1 0 0 0 0
1 1 0 1 1
此时第一行已全为1,然后再进行第二行
1 1 1 1 1
1 1 1 1 1
0 1 0 1 0
1 1 1 1 0
1 1 0 1 1
然后再对第三行进行
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
0 1 0 1 1
0 1 1 1 0
再进行第四行
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 0 0 0
可见第五行已经不能再改变了,这样显然不能得到全为1的二维数组,说明当第一行元素是这样的情况就不能成立
所以我们可以对第一行进行改变,只需要枚举第一行五个开关即可,然后按刚才的方法看是否能够全部变为1.

#include<bits/stdc++.h>
using namespace std;
const int Inf=0x3f3f3f;
const int MAXN=10;
int map1[MAXN][MAXN];
int map2[MAXN][MAXN];
int check;
int checking(int t)
{
    int sum=t;
    for(int i=1;i<=5;i++)
        for(int j=1;j<=5;j++)
            map2[i][j]=map1[i][j];
    for(int i=1;i<=4;i++)
    {
        for(int j=1;j<=5;j++)
        {
            if(!map2[i][j])
            {
                sum++;
                map2[i][j]=!map2[i][j];
                map2[i+1][j]=!map2[i+1][j];
                map2[i+1][j-1]=!map2[i+1][j-1];
                map2[i+1][j+1]=!map2[i+1][j+1];
                map2[i+2][j]=!map2[i+2][j];

            }
        }

    }
    for(int i=1;i<=5;i++)
        if(!map2[5][i])
            return Inf;
    return sum;
}
void dfs(int x,int y)//x为第一行元素的下标,y为第一行打开开关的次数 
{
    if(x>5)
    {
        check=min(check,checking(y));
        return;
    }
    map1[1][x]=!map1[1][x];
    map1[1][x-1]=!map1[1][x-1];
    map1[1][x+1]=!map1[1][x+1];
    map1[2][x]=!map1[2][x];
    dfs(x+1,y+1);
    map1[1][x]=!map1[1][x];
    map1[1][x-1]=!map1[1][x-1];
    map1[1][x+1]=!map1[1][x+1];
    map1[2][x]=!map1[2][x];
    dfs(x+1,y);

}
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {

        for(int i=1;i<=5;i++)
        {
            for(int j=1;j<=5;j++)
            {
                scanf("%1d",&map1[i][j]);
            }
        }
        check=Inf;
        dfs(1,0);
        if(check<7)
            printf("%d\n",check);
        else
            printf("-1\n");
    }
    return 0;
}