Sei sulla pagina 1di 3

#include <cstdio>

#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 35;
int T, N, K, board [MAXN], low [MAXN], top [MAXN];
int value [MAXN][MAXN], flip [MAXN][MAXN];
bool last [MAXN];
char str [MAXN];
inline bool light (int r, int c)
{
return board [r] & 1 << c;
}
inline int get (int r)
{
int val = top [r];
val ^= top [r] << 1;
val ^= top [r] >> 1;

if (r > 0)
val ^= top [r - 1];
val &= (1 << N) - 1;
return val;
}
int gaussian (int *mask, bool *res)
{
for (int i = 0; i < N; i++)
for (int j = i; j < N; j++)
if (mask [j] & 1 << i)
{
for (int k = j + 1; k < N; k++)
if (mask [k] & 1 << i)
{
mask [k] ^= mask [j];
res [k] ^= res [j];
}
swap (mask [i], mask [j]);
swap (res [i], res [j]);
break;
}
int on = 0;
for (int i = N - 1; i >= 0; i--)
{
for (int j = i + 1; j < N; j++)
if (mask [j] != 0 && (mask [i] & 1 << low [j]) != 0)
{
mask [i] ^= mask [j];
res [i] ^= res [j];
}
low [i] = __builtin_ctz (mask [i]);
/*
if (mask [i] == 0 && res [i])
puts ("BAD");
*/
if (mask [i] != 0 && res [i])
on |= 1 << low [i];
}
return on;
}
int main ()
{
for (scanf ("%d", &T); T > 0; T--)
{
memset (board, 0, sizeof (board));
scanf ("%d", &N);
for (int i = 0; i < N; i++)
{
scanf ("%s", str);

for (int j = 0; j < N; j++)


board [i] |= (str [j] - '0') << j;
}
memset (value, 0, sizeof (value));
memset (flip, 0, sizeof (flip));
for (int i = 0; i < N; i++)
flip [0][i] = 1 << i;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (light (i, j))
value [i][j] = 1 << N;
value [i][j] ^= flip [i][j];
if (i > 0)
value [i][j] ^= flip [i - 1][j];

if (j > 0)
value [i][j] ^= flip [i][j - 1];
if (j + 1 < N)
value [i][j] ^= flip [i][j + 1];
}
for (int j = 0; j < N; j++)
flip [i + 1][j] = value [i][j];
}
for (int i = 0; i < N; i++)
{
last [i] = (value [N - 1][i] & 1 << N) == 0 ? 0 : 1;
value [N - 1][i] &= (1 << N) - 1;
}
top [0] = gaussian (value [N - 1], last);
for (int i = 1; i < N; i++)
top [i] = board [i - 1] ^ get (i - 1);
K = 0;
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
if (top [i] & 1 << j)
K++;
printf ("%d\n", K);
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
if (top [i] & 1 << j)
printf ("%d %d\n", i + 1, j + 1);
}
return 0;
}

Potrebbero piacerti anche