Cod sursa(job #3256259)

Utilizator vladimir.gavris.1Gavris Mihai Vladimir vladimir.gavris.1 Data 13 noiembrie 2024 22:08:47
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.33 kb
#include <fstream>
#include <queue>

using namespace std;

ifstream in( "barbar.in" );
ofstream out( "barbar.out" );

#define MAXN 1000
#define INF 2000000000
#define DIR 4

struct point
{
    int lin, col;
};


int n, m;
queue<point> qu;
int dist[ MAXN + 2 ][ MAXN + 2 ];
bool hero[ MAXN + 2 ][ MAXN + 2 ];

point st, nd;
int answ = 0;

int dlin[ ] = { -1, 0, 1, 0 };
int dcol[ ] = { 0, -1, 0, 1 };

point formpoint( int i, int j )
{
    point a;
    a.lin = i, a.col = j;
    return a;
}

bool check( point a )
{
    return ( a.lin >= 1 && a.col >= 1 && a.lin <= n && a.col <= m);
}

void clear_hero( )
{
    for( int i = 1; i <= n; i++ )
    {
        for( int j = 1; j <= m; j++ )
        {
            hero[ i ][ j ] = 0;
        }
    }
}

void lee( )
{
    while( !qu.empty( ) )
    {
        point current = qu.front( );
        qu.pop( );

        for( int i = 0; i < DIR; i++ )
        {
            point next;
            next.lin = current.lin + dlin[ i ], next.col = current.col + dcol[ i ];
            if( check( next ) == true && dist[ next.lin ][ next.col ] == -1 )
            {
                dist[ next.lin ][ next.col ] = dist[ current.lin ][ current.col ] + 1;
                qu.push( next );
            }
        }
    }
}

bool leehero( int val )
{
    clear_hero( );

    queue<point> q;
    q.push( st );
    hero[ st.lin ][ st.col ] = 1;

    while( !q.empty( ) )
    {
        point current = q.front( );
        q.pop( );

        if( current.lin == nd.lin && current.col == nd.col )
        {
            return true;
        }

        for( int i = 0; i < DIR; i++ )
        {
            point next;
            next.lin = current.lin + dlin[ i ], next.col = current.col + dcol[ i ];

            if( check( next ) == true && dist[ next.lin ][ next.col ] >= val && hero[ next.lin ][ next.col ] == 0 )
            {
                hero[ next.lin ][ next.col ] = 1;
                q.push( next );
            }
        }
    }
    return false;
}

void bsearch( )
{
    int left = 1, right = 1e7;
    while( left <= right )
    {
        int mid = ( left + right ) / 2;

        if( leehero( mid ) == true && dist[ st.lin ][ st.col ] >= mid )
        {
            left = mid + 1;
            answ = mid;
        }
        else
        {
            right = mid - 1;
        }
    }
}

int main()
{
    char c;
    in >> n >> m;

    for( int i = 1; i <= n; i++ )
    {
        for( int j = 1; j <= m; j++ )
        {
            in >> c;
            if( c == '.' )
            {
                dist[ i ][ j ] = -1;
            }
            else if( c == '*' )
            {
                dist[ i ][ j ] = -2;
            }
            else if( c == 'D' )
            {
                dist[ i ][ j ] = 0;
                qu.push( formpoint( i, j ) );
            }
            else if( c == 'I' )
            {
                dist[ i ][ j ] = -1;
                st = formpoint( i, j );
            }
            else if( c == 'O' )
            {
                dist[ i ][ j ] = -1;
                nd = formpoint( i, j );
            }
        }
    }

    lee( );
    bsearch( );

    if( answ == 0 )
    {
        out << -1;
    }
    else
    {
        out << answ;
    }
    return 0;
}