/*
ID: lucien23
PROG: castle
LANG: C++
*/
/************************************************************************/
/* 求图的连通域问题。利用广度扫描 */
/************************************************************************/
#include <iostream>
#include <fstream>
#include <map>
#include <vector>
#include <queue>
using namespace std;
typedef struct Position
{
int row;
int col;
Position(){}
Position (int r, int c)
{
row = r;
col = c;
}
} Position;
bool isPrior(Position pos1, char direction1, Position pos2, char direction2);
int main()
{
ifstream infile("castle.in");
ofstream outfile("castle.out");
if(!infile || !outfile)
{
cout << "file operation failure!" << endl;
return -1;
}
int M, N;
infile >> M >> N;
int ***walls = new int**[N];
for (int i=0; i<N; i++)
{
walls[i] = new int*[M];
for (int j = 0; j < M; j++)
{
walls[i][j] = new int[6]();
infile >> walls[i][j][0];
switch (walls[i][j][0])
{
case 0:
break;
case 1:
walls[i][j][1] = 1;
break;
case 2:
walls[i][j][2] = 1;
break;
case 3:
walls[i][j][1] = 1;
walls[i][j][2] = 1;
break;
case 4:
walls[i][j][3] = 1;
break;
case 5:
walls[i][j][1] = 1;
walls[i][j][3] = 1;
break;
case 6:
walls[i][j][2] = 1;
walls[i][j][3] = 1;
break;
case 7:
walls[i][j][1] = 1;
walls[i][j][2] = 1;
walls[i][j][3] = 1;
break;
case 8:
walls[i][j][4] = 1;
break;
case 9:
walls[i][j][1] = 1;
walls[i][j][4] = 1;
break;
case 10:
walls[i][j][2] = 1;
walls[i][j][4] = 1;
break;
case 11:
walls[i][j][1] = 1;
walls[i][j][2] = 1;
walls[i][j][4] = 1;
break;
case 12:
walls[i][j][3] = 1;
walls[i][j][4] = 1;
break;
case 13:
walls[i][j][1] = 1;
walls[i][j][3] = 1;
walls[i][j][4] = 1;
break;
case 14:
walls[i][j][2] = 1;
walls[i][j][3] = 1;
walls[i][j][4] = 1;
break;
case 15:
walls[i][j][1] = 1;
walls[i][j][2] = 1;
walls[i][j][3] = 1;
walls[i][j][4] = 1;
break;
default:
break;
}
}
}
vector<int> components;
int cnt = 0;
for (int i=0; i<N; i++)
{
for (int j=0; j<M; j++)
{
if (walls[i][j][5] == 0)
{
cnt++;
components.push_back(0);
queue<Position> nodes;
nodes.push(Position(i, j));
while (!nodes.empty())
{
Position pos = nodes.front();
int m = pos.row;
int n = pos.col;
int *currentNode = walls[m][n];
nodes.pop();
if (currentNode[5] != 0)
continue;
components[cnt-1]++;
currentNode[5] = cnt;
if (currentNode[1] == 0 && walls[m][n-1][5] == 0)
{
nodes.push(Position(m ,n-1));
}
if (currentNode[2] == 0 && walls[m-1][n][5] == 0)
{
nodes.push(Position(m-1, n));
}
if (currentNode[3] == 0 && walls[m][n+1][5] == 0)
{
nodes.push(Position(m, n+1));
}
if (currentNode[4] == 0 && walls[m+1][n][5] == 0)
{
nodes.push(Position(m+1, n));
}
}
}
}
}
int newRoom = 0;
Position wallPos;
char dirction;
for (int i=0; i<N; i++)
{
for (int j=0; j<M; j++)
{
if (walls[i][j][1] == 1 && j-1>=0 && walls[i][j][5] != walls[i][j-1][5])
{
int sum = components[walls[i][j][5]-1] + components[walls[i][j-1][5]-1];
Position newPos = Position(i, j-1);
if (sum > newRoom || (sum == newRoom && isPrior(newPos, 'E', wallPos, dirction)))
{
newRoom = sum;
wallPos = newPos;
dirction = 'E';
}
}
if (walls[i][j][2] == 1 && i-1>=0 && walls[i][j][5] != walls[i-1][j][5])
{
int sum = components[walls[i][j][5]-1] + components[walls[i-1][j][5]-1];
Position newPos = Position(i, j);
if (sum > newRoom || (sum == newRoom && isPrior(newPos, 'N', wallPos, dirction)))
{
newRoom = sum;
wallPos = newPos;
dirction = 'N';
}
}
if (walls[i][j][3] == 1 && j+1<M && walls[i][j][5] != walls[i][j+1][5])
{
int sum = components[walls[i][j][5]-1] + components[walls[i][j+1][5]-1];
Position newPos = Position(i, j);
if (sum > newRoom || (sum == newRoom && isPrior(newPos, 'E', wallPos, dirction)))
{
newRoom = sum;
wallPos = newPos;
dirction = 'E';
}
}
if (walls[i][j][4] == 1 && i+1<N && walls[i][j][5] != walls[i+1][j][5])
{
int sum = components[walls[i][j][5]-1] + components[walls[i+1][j][5]-1];
Position newPos = Position(i+1, j);
if (sum > newRoom || (sum == newRoom && isPrior(newPos, 'N', wallPos, dirction)))
{
newRoom = sum;
wallPos = newPos;
dirction = 'N';
}
}
}
}
int maxRoom = components[0];
for (int i=1; i<cnt; i++)
{
if (components[i] > maxRoom)
maxRoom = components[i];
}
outfile << cnt << endl << maxRoom << endl << newRoom << endl
<< wallPos.row+1 << " " << wallPos.col+1 << " " << dirction <<endl;
return 0;
}
bool isPrior(Position pos1, char direction1, Position pos2, char direction2)
{
if(pos1.col < pos2.col || (pos1.col == pos2.col && pos1.row > pos2.row)
|| (pos1.col == pos2.col && pos1.row == pos2.row && direction1 == 'N' && direction2 == 'E'))
{
return true;
}
return false;
}