题目链接 https://vjudge.net/contest/305270#problem/G
不太明算出来这个点的周围的1的个数后的操作,这一块 ,
b[i][j]=sum&1;
if (a[i][j]==1 && b[i][j]==0) return inf;
#include <bits/stdc++.h>
using namespace std;
const int inf=999999999;
int a[20][20],b[20][20],n;
int check(int s);
int main()
{
int t;
scanf ("%d",&t);
int cas=0;
while (cas<t){
scanf ("%d",&n);
for (int i=0; i<n; i++)
for (int j=0; j<n; j++)
scanf ("%d",&a[i][j]);
int ans=inf;
for (int i=0; i<(1<<n); i++){
ans=min(ans,check(i));
}
printf ("Case %d: ",++cas);
if (ans==inf) printf ("-1\n");
else printf ("%d\n",ans);
}
return 0;
}
int check(int s)
{
memset(b,0,sizeof(b));
int ans=0;
for (int i=0; i<n; i++){
if (s&(1<<i)) b[0][i]=1;
else if (a[0][i]) return inf;
}
for (int i=1; i<n; i++){//row
for (int j=0; j<n; j++){//col
int sum=0;
if(i>0) sum+=b[i-1][j];
if(i<n-1) sum+= b[i+1][j];
if (j>0) sum+=b[i-1][j-1];
if (j<n-1) sum+=b[i-1][j+1];
b[i][j]=sum&1;
if (a[i][j]==1 && b[i][j]==0) return inf;
}
}
for (int i=0; i<n; i++)
for (int j=0; j<n; j++){
if (a[i][j]!=b[i][j]) ans++;
}
return ans;
}
还可以用dfs做
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int oo=0x3f3f3f3f;
int a[20][20],n,ans,tem[20][20];
int cal(int i,int j)
{
int ret=0;
if (i>1) ret+=tem[i-1][j];
if (i<n) ret+=tem[i+1][j];
if (j>1) ret+=tem[i][j-1];
if (j<n) ret+=tem[i][j+1];
return ret;
}
int solve()
{
memcpy(tem,a,sizeof(a));
int i,j,ret=0;
for (i=2;i<=n;i++)
for (j=1;j<=n;j++)
if (cal(i-1,j)&1)
{
if (!tem[i][j])
{
tem[i][j]=1;
ret++;
}
else return oo;
}
for (i=1;i<=n;i++)
if (cal(n,i)&1) return oo;
return ret;
}
void dfs(int p,int now)
{
if (p==n+1)
{
ans=min(ans,now+solve());
return;
}
dfs(p+1,now);
if (!a[1][p])
{
a[1][p]=1;
dfs(p+1,now+1);
a[1][p]=0;
}
}
int main()
{
int T,K,i,j;
scanf("%d",&T);
for (K=1;K<=T;K++)
{
scanf("%d",&n);
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
scanf("%d",&a[i][j]);
ans=oo;
dfs(1,0);
printf("Case %d: ",K);
if (ans<oo) printf("%d\n",ans);
else printf("-1\n");
}
}