题意:
点击棋子,棋子本身和四周都会变色。问变全白或者全黑的最少步数。
构造16个方程组求解,需要枚举自由基。
#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
int equ,var;
int a[17][17]; //增广矩阵
int x[17]; //x的解系
int nofree_num,ans; //nofree_num 为非自由元的数量
void debug() //调试
{
int i,j;
for(i=0; i<equ; i++)
{
for(j=0; j<=var; j++) printf("%d ",a[i][j]);
puts("");
}
puts("");
}
void ok(int tep,int x,int y)
{
if(x<0||y<0||x>=4||y>=4) return;
a[tep][x*4+y]=1;
return;
}
void build() //构造初始系数矩阵
{
int i,j;
for(i=0; i<4; i++)
{
for(j=0; j<4; j++)
{
int tep=i*4+j;
ok(tep,i,j);
ok(tep,i,j+1);
ok(tep,i,j-1);
ok(tep,i+1,j);
ok(tep,i-1,j);
}
}
}
void dfs(int p) //无穷解的情况下 枚举不定元
{
if(p<nofree_num)
{
int i,j;
for(i=nofree_num-1; i>=0; i--)
{
int tep=a[i][var];
for(j=i+1; j<var; j++) tep^=a[i][j]*x[j];
x[i]=tep/a[i][i];
}
int sum=0;
for(i=0;i<equ;i++) sum+=x[i];
ans=min(ans,sum);
return ;
}
x[p]=0;
dfs(p-1);
x[p]=1;
dfs(p-1);
}
int gauss()
{
int i,j,k,row,col;
for(row=0,col=0; row<equ&&col<var ; row++,col++) //将系数矩阵化为上三角矩阵
{
for(i=row; i<equ; i++) if(a[i][col]) break;
if(i==equ)
{
row--;
continue;
}
for(j=0; j<=var; j++) swap(a[i][j],a[row][j]);
for(i=row+1; i<equ; i++)
{
if(a[i][col])
{
for(j=col; j<=var; j++)
a[i][j]^=a[row][j];
}
}
}
nofree_num=row;
for(i=row; i<equ; i++) if(a[i][var]) return -1; // 无解
for(i=0; i<equ; i++) //使得列和行对应(在之前不出现零列)
{
if(a[i][i]==0)
{
for(j=i+1; j<var; j++)
{
if(a[i][j]) break;
}
if(j==var) break;
for(k=0; k<equ; k++) swap(a[k][i],a[k][j]);
}
}
if(var-nofree_num) //无穷解
{
ans=999999999;
dfs(var-1);
return ans;
}
int sum=0; //唯一解 直接回代求解
for(i=row-1; i>=0; i--)
{
int tep=a[i][var];
for(j=i+1; j<var; j++) tep^=a[i][j]*x[j];
x[i]=tep/a[i][i];
sum+=x[i];
}
return sum;
}
int main()
{
char v[6][6];
while(cin>>v[0])
{
int i,j;
int f1,f2;
equ=var=16;
for(i=1; i<4; i++) cin>>v[i];
memset(a,0,sizeof(a));
build();
for(i=0; i<4; i++)
{
for(j=0; j<4; j++)
{
if(v[i][j]=='w') a[i*4+j][var]=0;
else a[i*4+j][var]=1;
}
}
f1=gauss();
memset(a,0,sizeof(a));
build();
for(i=0; i<4; i++)
{
for(j=0; j<4; j++)
{
if(v[i][j]=='w') a[i*4+j][var]=1;
else a[i*4+j][var]=0;
}
}
f2=gauss();
if(f1==-1&&f2==-1)
{
puts("Impossible");
continue;
}
if(f1==-1) printf("%d\n",f2);
else if(f2==-1) printf("%d\n",f1);
else printf("%d\n",min(f1,f2));
}
}