题目大意:
给出一个N*N的01矩阵,将矩阵中的t个0换成1,使得每一个数的四个方向的数之和为偶数。求最小的t.
思路:
只枚举第一行,然后推出下几行的数值。枚举第一行用到了位运算的方法.
附上AC代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=1e9;
int grid[20][20],tmp[20][20];
int T,n;
int ans,kase;
int _find(int t){
memset(tmp,0,sizeof(tmp));
for(int i=0;i<n;i++){
if(t&(1<<i))tmp[0][i]=1;
else if(grid[0][i]==1)return INF;
}
int cnt;
for(int i=1;i<n;i++){
for(int j=0;j<n;j++){
cnt=0;
if(j>0)cnt+=tmp[i-1][j-1];
if(j<n-1)cnt+=tmp[i-1][j+1];
if(i>1)cnt+=tmp[i-2][j];
tmp[i][j]=cnt%2;
if(grid[i][j]&&!tmp[i][j])return INF;
}
}
cnt=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(grid[i][j]!=tmp[i][j])
cnt++;
}
}
return cnt;
}
int main(){
ios::sync_with_stdio(false);
cin>>T;
kase=0;
while(T--){
ans=INF;
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>grid[i][j];
}
}
for(int i=0;i<(1<<n);i++){
ans=min(ans,_find(i));
}
cout<<"Case "<<++kase<<": ";
if(ans==INF)cout<<-1<<endl;
else cout<<ans<<endl;
}
return 0;
}