做法:
枚举第一行的所有的情况。然后根据第一行的情况,推出第二行,以此类推
然后就是原来矩阵中的1不能变成0.
根据前两行推出这一行,就是一个点的上下左右加起来要等于偶数。根据这一个推的。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int inf=1<<29;
const int maxn=30;
int n,ans;
int num[maxn][maxn];
int a[maxn][maxn];
int vis[maxn];
int f=0;
int xx[3]= {-1,-1,-2},yy[3]= {-1,1,0};
void chuli()
{
for(int i=0; i<n; i++)
if(num[0][i]==1&&a[0][i]==0)
return ;
for(int i=1; i<n; i++)
{
for(int j=0; j<n; j++)
{
int sum=0;
for(int k=0; k<3; k++)
{
int X=i+xx[k],Y=j+yy[k];
if(X>=0&&X<n&&Y>=0&&Y<n)
{
sum+=a[X][Y];
}
}
a[i][j]=(sum%2);
}
}
int sum=0;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
{
if(num[i][j]==1&&a[i][j]!=1)
return ;
if(num[i][j]!=a[i][j])
sum++;
}
ans=min(ans,sum);
}
void dfs(int cur)
{
if(cur==n)
{
chuli();
return ;
}
if(!a[0][cur])
{
a[0][cur]=1;
dfs(cur+1);
a[0][cur]=0;
}
dfs(cur+1);
}
int main()
{
int tt,kj=1;
scanf("%d",&tt);
while(tt--)
{
scanf("%d",&n);
memset(a,0,sizeof(a));
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
scanf("%d",&num[i][j]);
ans=inf;
dfs(0);
printf("Case %d: ",kj++);
if(ans==inf) printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}