Cod sursa(job #2243507)

Utilizator MaxTeoTeo Oprescu MaxTeo Data 20 septembrie 2018 19:01:16
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.74 kb
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;

FILE *f = freopen( "barbar.in", "r", stdin );
FILE *g = freopen( "barbar.out", "w", stdout );

int n, m, a[1005][1005], b[1005][1005], maxD;
int sx, sy, fx, fy;
int dx[4] = { -1, 0, 1,  0};
int dy[4] = {  0, 1, 0, -1};
queue< pair<int,int> > q;

void Read()
{
    char s[1005];
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i)
    {
        scanf("%s", s+1 );
        for(int j = 1; j <= m; ++j)
        {
            if( s[j] == '.' )
                a[i][j] = -1;
            else
            if( s[j] == '*' )
                a[i][j] = -2;
            else
            if( s[j] == 'I' )
            {
                sx = i, sy = j;
                a[i][j] = -1;
            }
            else
            if( s[j] == 'O' )
            {
                fx = i, fy = j;
                a[i][j] = -1;
            }
            else
                q.push( {i,j} );
        }
    }
}

bool isOk (int x, int y)
{
    return 0 < x && x <= n && 0 < y && y <= m && a[x][y] == -1;
}

void Distances()
{
    while( !q.empty() )
    {
        pair<int,int> cell = q.front();
        q.pop();

        for( int i = 0; i <= 3; ++i )
            if ( isOk( cell.x + dx[i], cell.y + dy[i]) )
            {
                a[cell.x + dx[i]][cell.y + dy[i]] = a[cell.x][cell.y] + 1;
                q.push( {cell.x + dx[i], cell.y + dy[i]} );
                maxD = max( maxD, a[cell.x + dx[i]][cell.y + dy[i]]);
            }
    }
}

bool isOkFill (int x, int y, int val)
{
    return 0 < x && x <= n && 0 < y && y <= m && ( b[x][y] >= val || b[x][y] == -3 ) && b[x][y] != -1;
}


void Fill( int x, int y, int val)
{
    b[x][y] = -1;

    if( b[fx][fy] == -1 )
        return;

    if( isOkFill( x - 1, y, val ) )
        Fill( x - 1, y, val );

    if( isOkFill( x, y + 1, val ) )
        Fill( x, y + 1, val );

    if( isOkFill( x + 1, y, val ) )
        Fill( x + 1, y, val );

    if( isOkFill( x, y - 1, val ) )
        Fill( x, y - 1, val );

}

bool There_is_a_Way( int val )
{

    if( a[sx][sy] < val || a[fx][fy] < val )
        return 0;

    for( int i = 1; i <= n; ++i )
        for( int j = 1; j <= m; ++j )
            b[i][j] = a[i][j];
    b[fx][fy] = -3;

    Fill( sx, sy, val );

    if( b[fx][fy] == -3)
        return 0;
    return 1;
}

void Solve_BS()
{
    int pas = 1 << 20, r = 0;

    while( pas )
    {
        if( r + pas <= maxD && There_is_a_Way( r + pas ) )
            r += pas;
        pas /= 2;
    }

    if( r )
        printf( "%d\n", r );
    else
        printf( "-1\n");
}

int main()
{
    Read();
    Distances();
    Solve_BS();
    return 0;
}