1 /* 2 题意:求最少改变多少个0成1,使得每一个元素四周的和为偶数 3 枚举:枚举第一行的所有可能(1<<n),下一行完全能够由上一行递推出来,b数组保存该位置需要填什么 4 最后检查不同的数量,取最小值 5 */ 6 #include <cstdio> 7 #include <algorithm> 8 #include <cstring> 9 using namespace std; 10 11 const int MAXN = 20; 12 const int INF = 0x3f3f3f3f; 13 int a[MAXN][MAXN], b[MAXN][MAXN]; 14 int n; 15 16 int check(int s) { 17 memset (b, 0, sizeof (b)); 18 for (int i=0; i<n; ++i) { 19 if (s & (1 << i)) b[0][i] = 1; 20 else if (a[0][i] == 1) return INF; 21 } 22 23 for (int i=1; i<n; ++i) { 24 for (int j=0; j<n; ++j) { 25 int sum = 0; 26 if (i > 1) sum += b[i-2][j]; 27 if (j > 0) sum += b[i-1][j-1]; 28 if (j < n-1) sum += b[i-1][j+1]; 29 b[i][j] = sum % 2; 30 if (a[i][j] == 1 && b[i][j] == 0) return INF; 31 } 32 } 33 34 int ret = 0; 35 for (int i=0; i<n; ++i) { 36 for (int j=0; j<n; ++j) { 37 if (a[i][j] != b[i][j]) ret++; 38 } 39 } 40 41 return ret; 42 } 43 44 int main(void) { //UVA 11464 Even Parity 45 //freopen ("G.in", "r", stdin); 46 47 int t, cas = 0; scanf ("%d", &t); 48 while (t--) { 49 scanf ("%d", &n); 50 for (int i=0; i<n; ++i) { 51 for (int j=0; j<n; ++j) { 52 scanf ("%d", &a[i][j]); 53 } 54 } 55 56 int ans = INF; 57 for (int i=0; i<(1<<n); ++i) { 58 ans = min (ans, check (i)); 59 } 60 61 if (ans == INF) ans = -1; 62 printf ("Case %d: %d\n", ++cas, ans); 63 } 64 65 return 0; 66 }
时间: 2024-11-05 20:47:35