题意同poj 1222 这题问你要涂多少次,但是有可能出现无解的情况。
无解的判断详见线性代数。
这题数据比较水,其实是需要枚举自由基的。
#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
int equ,var;
int a[17*17][17*17]; //增广矩阵
int x[17*17]; //x的解系
int nofree_num,ans; //nofree_num 为非自由元的数量
int gcd(int x,int y)
{
return y?gcd(y,x%y):x;
}
int lcm(int x,int y)
{
return x/gcd(x,y)*y;
}
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,int n)
{
if(x<0||y<0||x>=n||y>=n) return;
a[tep][x*n+y]=1;
return;
}
void build(int n) //构造初始系数矩阵
{
int i,j;
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
int tep=i*n+j;
ok(tep,i,j,n);
ok(tep,i,j+1,n);
ok(tep,i,j-1,n);
ok(tep,i+1,j,n);
ok(tep,i-1,j,n);
}
}
}
void dfs(int p)
{
if(p<nofree_num)
{
int i,j;
for(i=nofree_num-1; i>=0; i--)
{
int tep=a[i][var]%2;
for(j=i+1; j<var; j++)
tep=(tep-a[i][j]*x[j]%2+2)%2;
x[i]=(tep/a[i][i])%2;
}
int sum=0;
for(i=0; i<var; 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;
int row,col;
for(row=0,col=0; row<equ&&col<var; row++,col++)
{
int max_r=row;
for(i=row+1; i<equ; i++) if(abs(a[i][col])>abs(a[max_r][col])) max_r=i;
if(a[max_r][col]==0)
{
row--;
continue;
}
for(i=0; i<=var; i++) swap(a[row][i],a[max_r][i]);
for(i=row+1; i<equ; i++)
{
if(a[i][col])
{
int LCM=lcm(abs(a[row][col]),abs(a[i][col]));
int ta=LCM/abs(a[row][col]);
int tb=LCM/abs(a[i][col]);
if(a[row][col]*a[i][col]<0) ta=-ta;
for(j=col; j<=var ; j++)
a[i][j]=(a[i][j]*tb%2-a[row][j]*ta%2+2)%2;
}
}
}
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-row)
{
ans=99999999;
dfs(var-1);
return ans;
}
int sum=0;
for(i=row-1; i>=0; i--)
{
int tep=a[i][var]%2;
for(j=i+1; j<var; j++)
tep=(tep-a[i][j]*x[j]%2+2)%2;
x[i]=(tep/a[i][i])%2;
}
for(i=0; i<var; i++) sum+=x[i];
return sum;
}
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
int i,j;
equ=var=n*n;
char v[17][17];
for(i=0; i<n; i++) cin>>v[i];
memset(a,0,sizeof(a));
build(n);
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
if(v[i][j]=='w') a[i*n+j][var]=1;
else a[i*n+j][var]=0;
}
}
ans=gauss();
if(ans==-1) puts("inf");
else printf("%d\n",ans);
}
}