#include<iostream>
using namespace std;
int flag;
int step;
int loction[6][6];
int r[16] = { 0 };
int c[16] = { 0 };
void turn(int i, int j) //转换
{
for (int q = 0; q < 4; q++)
{
loction[i][q] = !(loction[i][q]);
}
for (int p = 0; p < 4; p++)
{
if (p != i)
{
loction[p][j] = !(loction[p][j]);
}
}
}
int range()//判定表格是否全部一样
{
int i, j;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
if (loction[i][j] != 1)
{
return 0;
}
}
}
return 1;
}
int DFS(int i, int j, int dp)//深搜(dp<=step)
{
//对第dp次的转换作判断
if (dp == step)
{
flag = range();
return 0;
}
if (flag || i == 4)
{
return 1;
}
//没有以上两种可以直接退出函数的情况,
//说明此时的dp<step,就进行第dp+1次的转换
turn(i, j);
//对当前转换的主位置(i,j)作记录
r[dp] = i+1;
c[dp] = j + 1;
//对第dp+1次的转换进行判断
if (j < 3)
{
//判断的是第dp+1次时转换的turn(i,j),
//如果判断成功,直接退出函数。
//如果判断失败,要继续进行下一列(即j+1)的递归转换和判断
//j+1不影响对第dp+1次转换的turn(i,j)的判断
//因为在DFS()函数里,判断turn(i,j)的步骤总在turn(i,j+1)前面
DFS(i, j+1, dp + 1);
}
else
{
//判断的是第dp+1次时转换的turn(i,j),
//如果判断成功,直接退出函数。
//如果判断失败,要继续进行下一行(即i+1)的递归转换和判断
//i+1不影响对第dp+1次转换的turn(i,j)的判断
//因为在DFS()函数里,判断turn(i,j)的步骤总在turn(i+1,j)前面
DFS(i + 1, 0, dp+1);
}
turn(i, j); //不符合条件,重新转换回来
//第dp次时,表格恢复初始状态
if (j < 3)
{
DFS(i, j + 1, dp ); //进行对下一列进行第dp次的转换()
}
else
{
DFS(i + 1, 0, dp); //进行对下一行进行第dp次的转换
}
return 0;
}
int main()
{
char tmp;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
scanf("%c", &tmp);
if (tmp == '-')
{
loction[i][j] = 1;
}
else
{
loction[i][j] = 0;
}
}
getchar(); //不要遗忘
}
for (step = 0; step <= 16; step++)
{
flag = 0;
DFS(0, 0, 0);
if (flag)
break;
}
if (flag)
{
cout << step << endl;
for (int i = 0; i < step; i++)
{
cout << r[i] << " " << c[i] << endl;
}
}
return 0;
}