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 );
}

Reply via email to