描述
给你一个 n×n 的01矩阵(每个元素非 0 即 1),你的任务是把尽量少的 0 变成 1,使得每个元素的上、下、左、右的元素(如果存在的话)之和均为偶数。比如,左边所示的矩阵至少要把 3 个 0 变成 1,最终右边图所示,才能保证其为偶数矩阵。
输入描述
第一行是正整数 n,接下来的 n 行每行包含 n 个非 0 即 1 的整数,相邻整数间用一个空格隔开。
输出描述
对于每组数据,输出被改变的元素的最小个数。如果无解,应输出 −1。
样例输入 1
3
0 0 0
1 0 0
0 0 0
样例输出 1
3
#include<bits/stdc++.h>
using namespace std;
int ans=230,n,a[20][20],b[20][20];
int check(int s){
memset(b,0,sizeof(b));
//将s展开为二进制放在b数组的第一行
for(int i=n-1;i>=0;i--){
b[0][i]=s%2;
if(a[0][i]==1&&b[0][i]==0){ //a数组的1不能变成0
return 230;
}
s=s>>1; // s/=2;
}
//根据第一行填充剩下的n-1行
for(int i=1;i<n;i++){
for(int j=0;j<n;j++){
int sum=0;
if(i>=2) sum+=b[i-2][j]; //上上方
if(j>0) sum+=b[i-1][j-1]; //左上方
if(j<n-1) sum+=b[i-1][j+1]; //右上方
b[i][j]=sum%2;
if(a[i][j]==1&&b[i][j]==0){ //a数组的1不能变成0
return 230;
}
}
}
//比较并返回a数组和b数组的差异
int cnt=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(a[i][j]!=b[i][j]){
cnt++;
}
}
}
return cnt;
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>a[i][j];
}
}
for(int i=0;i<(1<<n);i++){ //枚举第一行的十进制数据 1<<n === 2的n次方
ans=min(ans,check(i));
}
cout<<(ans==230?-1:ans);
return 0;
}