思路同poj 1222 EXTENDED LIGHTS OUT一样,只是多了个判断解的情况。
http://blog.csdn.net/shiren_Bod/article/details/5766907 这是poj 1222 的讲解,思路都是一样的。代码是kuangbin的模板。。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int MAXN = 300;
int g[MAXN][MAXN];
int equ,var;
int res[MAXN],freeX[MAXN];
int fnum,n;
void init()
{
memset(g,0,sizeof(g));
memset(res,0,sizeof(res));
fnum = 0;
equ = n*n;
var = n*n;
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < n; ++j)
{
int t = i*n+j;
g[t][t] = 1;
if(i > 0) g[(i-1)*n+j][t] = 1;
if(i < n-1) g[(i+1)*n+j][t] = 1;
if(j > 0) g[i*n+j-1][t] = 1;
if(j < n-1) g[i*n+j+1][t] = 1;
}
}
}
int Gauss()
{
int maxR,col,k;
fnum = 0;
for(k = 0, col = 0; k < equ && col < var; ++k, ++col)
{
maxR = k;
for(int i = k+1; i < equ; ++i)
if(abs(g[i][col]) > g[maxR][col])
maxR = i;
//记录自由变量
if(g[maxR][col] == 0)
{
k--;
freeX[fnum++] = col;
continue;
}
if(maxR != k)
{
for(int j = col; j < var+1; ++j)
swap(g[k][j],g[maxR][j]);
}
for(int i = k+1; i < equ; ++i)
{
if(g[i][col] != 0)
for(int j = col; j < var+1; ++j)
g[i][j] ^= g[k][j];
}
}
//方程无解
for(int i = k; i < equ; ++i)
if(g[i][col] != 0)
return -1;
if(k < var) return var-k;//解不唯一
//唯一解
for(int i = var-1; i >= 0; --i)
{
res[i] = g[i][var];
for(int j = i+1; j < var; ++j)
res[i] ^= (g[i][j]&&res[j]);
}
return 0;
}
void solve()
{
int t = Gauss();
if(t == -1)
{
puts("inf");
return;
}
else if(t == 0)
{
int ret = 0;
for(int i = 0; i < n*n; ++i)
ret += res[i];
printf("%d\n",ret);
}
else
{
//枚举自由变量
int ret = 0x3fffffff;
int tot = (1<<t);
//共t个自由变量,共tot种组合
for(int i = 0; i < tot; ++i)
{
int cnt = 0;
//枚举每种组合,包含的变元为1,不包含的就是0了
for(int j = 0; j < t; ++j)
{
if(i&(1<<j))
{
res[freeX[j]] = 1;
cnt++;
}
else
res[freeX[j]] = 0;
}
for(int j = var-t-1; j >= 0; --j)
{
int idx;
for(idx = j; idx < var; ++idx)
if(g[j][idx])
break;
res[idx] = g[j][var];
for(int l = idx+1; l < var; ++l)
if(g[j][l])
res[idx] ^= res[l];
cnt += res[idx];
}
ret = min(ret,cnt);
}
printf("%d\n",ret);
}
}
int main()
{
char op;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
init();
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < n; ++j)
{
scanf(" %c",&op);
//黄色为0,白色为1
if(op == 'y') g[i*n+j][n*n] = 0;
else g[i*n+j][n*n] = 1;
}
}
solve();
}
return 0;
}