Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
#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);
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;
}