Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 37055 | Accepted: 16125 |
Description
Input
Output
Sample Input
bwwb bbwb bwwb bwww
Sample Output
4
思路:
和前面那些问题差不多吧,只是它最后结果要求全黑或者全白,所以算了两次
poj1753 /* 同样的基于二维矩阵的开关问题,只是题目要求最终结果要 全亮或者全黑,于是算两次即可 */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <cmath> using namespace std; typedef long long ll; typedef long double ld; using namespace std; const int maxn = 40; int equ,var; int a[maxn][maxn]; int b[maxn][maxn]; int x[maxn]; int free_x[maxn]; int free_num; int Gauss() { int max_r,col,k; free_num = 0; for(k = 0,col = 0; k < equ && col < var; k++,col++) { max_r = k; for(int i = k+1; i < equ; i++) { if(abs(a[i][col]) > abs(a[max_r][col])) max_r = i; } if(a[max_r][col] == 0) { k --; free_x[free_num++] = col; continue; } if(max_r != k) { for(int j = col; j < var+1; j++) swap(a[k][j],a[max_r][j]); } for(int i = k + 1; i < equ; i++) { if(a[i][col] != 0) { for(int j = col; j < var+1; j++) a[i][j] ^= a[k][j]; } } } for(int i = k; i < equ; i++) if(a[i][col] != 0) return -1; if(k < var) return var-k; for(int i = var-1; i >= 0; i--) { x[i] = a[i][var]; for(int j = i +1; j < var; j++) x[i] ^= (a[i][j] && x[j]); } return 0; } int n; void ini() { memset(a,0,sizeof(a)); memset(x,0,sizeof(x)); equ = n*n; var = n*n; for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { int tt = i*n+ j; a[tt][tt] =1; b[tt][tt] = 1; if(i > 0) a[(i-1)*n+j][tt] = 1; if(i < n-1) a[(i+1)*n+j][tt] = 1; if(j > 0) a[tt-1][tt] = 1; if(j < n-1) a[tt+1][tt] =1; } } } int solve() { int t = Gauss(); if(t == -1) { return t; } else if(t == 0) { int ans = 0; for(int i = 0; i < n*n; i++) ans += x[i]; return ans; } else { int ans = 0x3f3f3f3f; int tot = (1 << t); for(int i = 0; i < tot; i++) { int cnt = 0; for(int j = 0; j < t; j++) { if(i & (1 << j)) { cnt ++; x[free_x[j]]= 1; } else x[free_x[j]]= 0; } for(int j = var-t-1; j >= 0; j--) { int dex; for(dex = j; dex < var; dex++) if(a[j][dex]) break; x[dex] = a[j][var]; for(int l = dex +1; l <var ; l++) { if(a[j][l]) x[dex] ^= x[l]; } cnt += x[dex]; } ans = min(ans,cnt); } return ans; } } char str[30][30]; int main() { int T; char color; scanf("%d",&T); while(scanf("%s",str[0]) !=EOF) { n = 4; ini(); for(int j = 0; j < n; j++) { if(str[0][j] == 'b') { a[j][n*n] = 0; } else { a[j][n*n] = 1; } } for(int i = 1; i < n; i++) { scanf("%s",str[i]); for(int j = 0; j < n; j++) { if(str[i][j] == 'b') { a[i*n+j][n*n] = 0; } else { a[i*n+j][n*n] = 1; } } } int ans1 = solve(); //cout <<ans1 <<endl; ini(); for(int i = 0;i < n;i++) { for(int j = 0;j < n;j++) { if(str[i][j] == 'b') { a[i*n+j][n*n] = 1; } else { a[i*n+j][n*n] = 0; } } } int ans2 = solve(); //cout << ans2<<endl; if(ans1 == -1 && ans2 == -1) printf("Impossible\n"); else if(ans1 == -1) printf("%d\n",ans2); else if(ans2 == -1) printf("%d\n",ans1); else printf("%d\n",min(ans1,ans2)); } return 0; }