用深搜做该题时,对每一个点都遍历一遍会超时
所以应该对其优化
先来看例子
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;
}
京公网安备 11010502036488号