Hi Guys,
@Nicholas , thanks a lot for cool solution but actually I weren't
working on image processing. I was trying to solve
"http://codeforces.com/contest/828/problem/B". I really needed
finding connected components this time.
@Ivan, your solution is much more elegant than what I did. But I
find @Timon's solution with cartesian product a bit nicer in this
case since I love to see std function more and more.
Thanks guys for all your advises. D community is really the best.
Here is my solution to question. It seems I didn't get it working
completely yet. In my debugger(Msvc MonoD) even there are many
rows it seems Recurse function only loops the columns in the
first row. And debugger is jumping so strangely I couldn't tag
the problem.
But I don't expect a big change there should be a small bug that
is it.
Sorry if code contains some foreign words I just replaced many
variable names from my native language I might be missing some.
import std.stdio;
import std.string;
import std.algorithm;
import std.conv;
import std.array;
import std.range;
import std.math;
int totalrow;
int totalcolumn;
dchar[][] twoDimensionArray;
struct ConnectedElementsSolver
{
this( dchar[][] twoDimArray )
{
m_twoDimStruct = twoDimArray;
Recurse(0, 0);
}
void Recurse ( int row, int column )
{
if( row < 0 || column < 0 )
return;
for ( ; row < m_twoDimStruct.length ; row++ )
{
for ( ; column < m_twoDimStruct[row].length; column++
)
{
Process( row, column, m_twoDimStruct.length,
m_twoDimStruct[row].length );
}
}
}
void Process( int row, int column, ulong maxrow, ulong maxcolumn
)
{
if( row < 0 || column < 0 || row >= maxrow || column >=
maxcolumn )
return;
if ( m_twoDimStruct[row][column] == 'B' )
{
m_twoDimStruct[row][column] = 'W';
m_tempResult.Process(row, column );
Process(row-1,column-1, maxrow, maxcolumn);
Process(row,column-1, maxrow, maxcolumn);
Process(row+1,column-1, maxrow, maxcolumn);
Process(row-1,column, maxrow, maxcolumn);
Process(row+1,column, maxrow, maxcolumn);
Process(row-1,column+1, maxrow, maxcolumn);
Process(row,column+1, maxrow, maxcolumn);
Process(row-1,column+1, maxrow, maxcolumn);
}
else
{
if ( m_tempResult.HowManyFilled )
m_results ~= m_tempResult;
m_tempResult.Resetle();
}
}
SquareCandidate m_tempResult;
SquareCandidate[] m_results;
dchar[][] m_twoDimStruct;
}
struct SquareCandidate
{
int MaxY;
int MinY;
int MaxX;
int MinX;
int HowManyFilled;
this( int howManyFilled )
{
HowManyFilled = howManyFilled;
}
void Resetle()
{
this = SquareCandidate();
}
void Process( int row, int column )
{
HowManyFilled++;
MaxY = max( column, MaxY);
MinY = min( column, MinY);
MaxX = max( row, MaxX);
MinX = min( row, MinX);
}
int FindEmptySlots()
{
int kareKenarUzunlugu = max(MaxX-MinX, MaxY-MinY);
int kareAlani = kareKenarUzunlugu*kareKenarUzunlugu;
return kareAlani - HowManyFilled;
}
bool CanCreateSquare( int xMax, int yMax )
{
int xUzunlugu = MaxX-MinX;
int yUzunlugu = MaxY-MinY;
if ( xUzunlugu > yUzunlugu )
{
return yMax >= xUzunlugu;
}
else
{
return xMax >= yUzunlugu;
}
}
}
void main()
{
auto dimensions = stdin.readln.strip.split().map!(a =>
to!int(a)).array();
totalrow = dimensions[0];
totalcolumn = dimensions[1];
twoDimensionArray = stdin
.byLine()
.take(totalrow)
.map!(line => line
.map!(a => to!dchar(a))
.array())
.array;
ConnectedElementsSolver baglantiliElemCozucu =
ConnectedElementsSolver(twoDimensionArray);
bool isAnyProblemMakingSquare =
baglantiliElemCozucu.m_results.any!(a =>
a.CanCreateSquare(totalrow, totalcolumn) == false );
if ( isAnyProblemMakingSquare )
writeln(-1);
int sonuc;
baglantiliElemCozucu.m_results.each!( a => sonuc +=
a.FindEmptySlots() );
writeln( sonuc );
}