题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2459
题意:给个n*n的01矩阵,可以修改其中的0变成1,问最少修改几个0可以让所有位置中的上下左右的数字和为偶数。
枚举第一行,第二行可以递推得到,所以只需要2^n枚举,外加n*n的判断。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 22; 5 int a[maxn][maxn], b[maxn][maxn]; 6 int n; 7 int ret; 8 9 int main() { 10 // freopen("in", "r", stdin); 11 int T, _ = 1; 12 scanf("%d", &T); 13 while(T--) { 14 scanf("%d", &n); 15 ret = 0x7f7f7f; 16 for(int i = 0; i < n; i++) { 17 for(int j = 0; j < n; j++) { 18 scanf("%d", &a[i][j]); 19 } 20 } 21 int nn = 1 << n; 22 for(int i = 0; i < nn; i++) { 23 memset(b, 0, sizeof(b)); 24 bool flag = 0; 25 for(int j = 0; j < n; j++) { 26 if(i & (1 << j)) b[0][j] = 1; 27 if(a[0][j] == 1 && b[0][j] == 0) { 28 flag = 1; 29 break; 30 } 31 } 32 if(flag) continue; 33 for(int r = 1; r < n; r++) { 34 for(int c = 0; c < n; c++) { 35 int tmp = 0; 36 if(r > 1) tmp += b[r-2][c]; 37 if(c > 0) tmp += b[r-1][c-1]; 38 if(c < n - 1) tmp += b[r-1][c+1]; 39 b[r][c] = tmp % 2; 40 if(a[r][c] == 1 && b[r][c] == 0) { 41 flag = 1; 42 break; 43 } 44 } 45 } 46 if(flag) continue; 47 int cnt = 0; 48 for(int r = 0; r < n; r++) { 49 for(int c = 0; c < n; c++) { 50 if(a[r][c] != b[r][c]) cnt++; 51 } 52 } 53 ret = min(ret, cnt); 54 } 55 printf("Case %d: ", _++); 56 printf("%d ", ret == 0x7f7f7f ? -1 : ret); 57 } 58 return 0; 59 }