#include <iostream>
#include <stack>
#include <vector>
using namespace std;
int resolution(vector< vector<int> > &A)
{
//self-defined construct
struct Point
{
int line;
int col;
Point(int X, int Y) :
line(X), col(Y)
{
}
~Point()
{
}
};
//allocate bitArray for Nodes' visited 0-1 state
int N = A.size();
int M = A.at(0).size();
char *isChecked = new char[(N * M + 8) / 8];
if (isChecked == NULL)
{
return -1;
}
//initialize all node with all unvisited state.
for (int i = 0; i < (N * M + 8) / 8; ++i)
{
isChecked[i] = 0;
}
int currColor = -1;
stack<Point> currS;// diagram's depth-first traversal algorithm
int totalCn = 0;
for (int ii = 0; ii < N; ++ii)
{
for (int jj = 0; jj < M; ++jj)
{
if ((isChecked[(ii * M + jj) / 8] & (1 << ((ii * M + jj) % 8))) == 0)
{ // if current Node not yet been visited, set visited.
isChecked[(ii * M + jj) / 8] |= (1 << ((ii * M + jj) % 8));
currS.push(Point(ii, jj));// a new 4-branch tree's rootNode
++totalCn;
currColor = A[ii][jj];
//Start merging all Neighboring Same color Node whose value equals currColor
while (!currS.empty())
{
Point tmp = currS.top();
currS.pop();
int i = tmp.line;
int j = tmp.col;
//current node's right neighbor if exists
if ((j + 1 < M)
&& ((isChecked[(i * M + j + 1) / 8]
& (1 << ((i * M + j + 1) % 8))) == 0)
&& (A[i][j+1] == currColor))
{
isChecked[(i * M + j + 1) / 8] |= (1 << ((i * M + j + 1) % 8));
currS.push(Point(i, j + 1));
}
//current node's down neighbor if exists
if ((i + 1 < N)
&& ((isChecked[((i+1) * M + j) / 8]
& (1 << (((i+1) * M + j) % 8))) == 0)
&& (A[i+1][j] == currColor))
{
isChecked[((i+1) * M + j ) / 8] |= (1 << (((i+1) * M + j ) % 8));
currS.push(Point(i+1, j ));
}
//current node's left neighbor if exists
if ((j - 1 >=0)
&& ((isChecked[(i * M + j - 1) / 8]
& (1 << ((i * M + j - 1) % 8))) == 0)
&& (A[i][j-1] == currColor))
{
isChecked[(i * M + j - 1) / 8] |= (1 << ((i * M + j - 1) % 8));
currS.push(Point(i, j - 1));
}
//current node's upper neighbor if exists
if ((i - 1 >=0 )
&& ((isChecked[((i-1) * M + j ) / 8]
& (1 << (((i-1) * M + j ) % 8))) == 0)
&& (A[i-1][j] == currColor))
{
isChecked[((i-1) * M + j) / 8] |= (1 << (((i-1) * M + j ) % 8));
currS.push(Point(i-1, j));
}
}
}
}
}
delete[] isChecked;
isChecked = NULL;
return totalCn;
}
int main(int argc, char** argv)
{
cout << solution(A);
return 0;
}