高斯很好写,当有自由变元时再枚举一下自由变元就行了。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
#define sfint(x) scanf("%d",&x)
#define sfint2(x,y) scanf("%d%d",&x,&y)
#define sfint3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define sfstr(c) scanf("%s",c)
#define sfdl(x) scanf("%lf",&x)
#define sfch(c) scanf("%d",&c)
#define pfint(x) printf("%d\n",x)
#define fr(i,s,n) for(int i=s;i<n;++i)
#define _fr(i,n,s) for(int i=n-1;i>=s;--i)
#define cl(a) memset(a,0,sizeof(a))
int a[20][20];
int b[20][20];
int de[2][4] = {0,1,0,-1,1,0,-1,0};
int best = 20;
int x[20];
int lim;
int freeval(int r){
int ret=0;
fr(i , 16-lim,16) ret+=a[r][i]*x[i-(16-lim)];
return ret%2;
}
int cal(int cnt){
fr(i , 0 ,16-lim) cnt+=a[i][16]^freeval(i);
return cnt;
}
void dfs(int u,int cnt){
if (cnt>=best) return ;
if(u == lim){
best = min(best,cal(cnt));
return;
}
x[u] = 1;dfs(u+1,cnt+1);
x[u] = 0;dfs(u+1,cnt);
}
int gauss(int a[][20],int n){
int r,c;
for(r = 0, c=0;r<n,c<n;++r,++c){
int p = r;
fr(i , r+1,n){
if(a[i][c] > a[p][c]) p = i;
}
if (p != r){
fr(i , c,n+1){
swap(a[p][i],a[r][i]);
}
}
if(a[r][c] == 0){
r--;continue;
}
fr(i , 0,n){
if (a[i][c] == 0||i == r) continue;
fr(j,c,n+1) a[i][j] = a[i][j]^a[r][j];
}
}
fr(i , r,n) if (a[i][n]) return -1;
return n-r;
}
int main(){
#ifdef local
fi;
#endif
char c[6];
fr(i , 0 ,4){
sfstr(c);
fr(j , 0 ,4){
if (c[j] == 'b') a[i*4+j][16] = 1;
}
}
int cnt = 0;
fr(i , 0 ,16){
cnt+=a[i][16];
}
if(cnt == 0 || cnt == 16) {
puts("0");
return 0;
}
fr(i , 0 ,16){
a[i][i] = 1;
int r = i/4,c = i%4;
fr(d, 0,4){
int x = r+de[0][d],y = c+de[1][d];
if (x>=0 && x<=3 && y>=0 && y<= 3) a[x*4+y][i] = 1;
}
}
fr(i , 0 ,16){
fr(j , 0 ,16) b[i][j] = a[i][j];
b[i][16] = a[i][16] ^ 1;
}
int ans1=gauss(a,16);
if(ans1 != -1){
lim = ans1;
dfs(0,0);
}
fr(i , 0 ,16){
fr(j , 0 ,17) a[i][j] = b[i][j];
}
ans1=gauss(a,16);
if(ans1 != -1){
lim = ans1;
dfs(0,0);
}
if(best == 20) puts("Impossible");
else printf("%d\n",best);
return 0;
}