先枚举出第一行的 (2^n) 种状态,然后递推出后面所有的行
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 20;
const int INF = 1000000007;
int T, n;
int a[maxn][maxn], b[maxn][maxn], c[maxn], ans;
void check(int s){
int res = 0;
for(int i = 1 ; i <= n ; ++i) for(int j = 1 ; j <= n ; ++j) b[i][j] = a[i][j];
for(int i = 1 ; i <= n ; ++i){
if((s >> (n - i)) & 1){
if(a[1][i] == 0){
++res;
b[1][i] ^= 1;
} else{
return;
}
}
}
for(int i = 2 ; i <= n ; ++i){
for(int j = 1 ; j <= n ; ++j){
int sum = 0;
sum = b[i - 1][j - 1] + b[i - 1][j + 1] + b[i - 2][j];
if((sum & 1) && !a[i][j]){
b[i][j] ^= 1;
++res;
}
if(!(sum & 1) && a[i][j]){
return;
}
}
}
for(int i = 1 ; i <= n ; ++i){
if((b[n][i - 1] + b[n][i + 1] + b[n - 1][i]) & 1) return;
}
ans = min(ans, res);
return;
}
ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
int main(){
T = read();
for(int t = 1 ; t <= T ; ++t){
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
ans = INF;
n = read();
for(int i = 1 ; i <= n ; ++i) for(int j = 1 ; j <= n ; ++j) a[i][j] = read();
for(int s = 0 ; s < (1 << n) ; ++s){
check(s);
}
printf("Case %d: %d
", t, ans == INF? -1 : ans);
}
return 0;
}