/*
Time:2019.12.13
Author: Goven
type:
ref:https://www.cnblogs.com/geloutingyu/p/7571522.html
*/
法1:高斯消元
//高斯消元
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
int a[225][226];
int d[5][2] = {{0, 0}, {0, 1}, {0, -1}, {1, 0}, {-1, 0}};
int res;
void back (int n) {
int len = n * n;
int i, cnt = 0; //cnt表示随机变量的个数
for (i = len - 1; i >= 0; i--) {
if (a[i][len]) {
if (a[i][i] == 0) {
cout << "inf" << endl;
return;
}
break;
}
cnt++;
}
res = 300;
for (int j = 0; j < (1 << cnt); j++) {//随机变量遍历所有可能
int cnt = 0;
for (int k = 0; k < cnt; k++) {
if (j & (1 << k)) {
cnt++;
for (int t = i; t >= 0; t--) {
if (a[t][n - cnt]) a[t][len] = !a[t][len];
}
}
}
for (int k = i; k >= 0; k--) {
if (a[k][len]) cnt++;
}
res = min(res, cnt);
}
cout << res << endl;
}
void gauss (int n) {
int len = n * n;
for (int i = 0; i < len; i++) {
int k = i;
for (; k < len; k++) {
if (a[k][i]) break;
}
//交换行
if (k < len) {//err1:要判断k,不然k =len时会出错
for (int j = 0; j <= len; j++) {//att1: 别忘了=
swap(a[i][j], a[k][j]);
}
}
//消元
for (int j = 0; j < len; j++) {
if (i == j) continue;
if (a[j][i]) {
for (int k = i; k <= len; k++) {
a[j][k] ^= a[i][k];
}
}
}
}
back(n);
}
int main()
{
int t, n;
cin >> t;
while (t--) {
cin >> n;
memset(a, 0, sizeof(a));
char c;
int len = n * n;
for (int i = 0; i < len; i++) {
cin >> c;
if (c == 'w') a[i][len] = 1;
}
//扩展矩阵
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int ti = i * n + j;
for (int k = 0; k < 5; k++) {
int tx = i + d[k][0];
int ty = j + d[k][1];
if (tx < 0 || tx >= n || ty <0 || ty >= n) continue;
a[ti][tx * n + ty] = 1;
}
}
}
gauss(n);
}
return 0;
}
法2:枚举递推
//枚举递推
#include<iostream>
#include<cstring>
using namespace std;
int g[15][15], tp[15][15];
int d[5][2] = {{0, 0}, {0, 1}, {0, -1}, {1, 0}, {-1, 0}};
int res;
int judge (int s, int n) {
int cnt = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
tp[i][j] = g[i][j];
}
for (int i = 0; i < n; i++) {
if (s & (1 << i)) {
cnt++;
for (int j = 0; j < 5; j++) {
int tx = d[j][0];
int ty = i + d[j][1];
if (tx < 0 || tx >= n || ty < 0 || ty >= n) continue;
tp[tx][ty] = !tp[tx][ty];
}
}
}
for (int i = 1; i < n; i++) {
for (int j = 0; j < n; j++) {
if (tp[i - 1][j]) {
cnt++;
for (int k = 0; k < 5; k++) {
int tx = i +d[k][0];
int ty = j + d[k][1];
if (tx < 0 || tx >= n || ty < 0 || ty >= n) continue;
tp[tx][ty] = !tp[tx][ty];
}
}
}
}
for (int i = 0; i < n; i++) {
if (tp[n - 1][i]) {
return 300;
}
}
return cnt;
}
void solve (int n) {
for (int i = 0; i < (1 << n); i++) {
res = min(res, judge(i, n));
}
}
int main()
{
int t, n;
cin >> t;
while (t--) {
cin >> n;
memset(g, 0, sizeof(g));
res = 300;
char c;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> c;
if (c == 'w') g[i][j] = 1;
}
}
solve(n);
if (res == 300) cout << "inf" << endl;
else
cout << res << endl;
}
return 0;
}