Cod sursa(job #2178684)

Utilizator AndreiSorin26012001Cirpici Andrei Sorin AndreiSorin26012001 Data 19 martie 2018 17:40:35
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.49 kb
#include <bits/stdc++.h>

using namespace std;

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

int n, m, st, dr, mid;
int dragoni[1005][1005], pers[1005][1005];
char ch;

queue< pair<int, int> > drag, c;

int sx, sy, fx, fy;
int dx[4] = { -1,  0, 0, 1 };
int dy[4] = {  0, -1, 1, 0 };

void lee( queue< pair<int, int> >& coada, int a[][1005], bool (*OK)(int, int) )
{
    int x, y, x_n, y_n;

    while( !coada.empty() )
    {
        x = coada.front().first;
        y = coada.front().second;
        coada.pop();

        for( int d = 0; d <= 3; d++ )
        {
            x_n = x + dx[d];
            y_n = y + dy[d];

            if( OK( x_n, y_n ) )
            {
                a[x_n][y_n] = a[x][y] + 1;
                coada.push( make_pair(x_n, y_n) );
            }
        }
    }
}

bool ok1( int x, int y )
{
    if( x < 1 || y < 1 || x > n || y > m )
        return false;

    if( dragoni[x][y] != 0 )
        return false;

    return true;
}

bool ok2( int x, int y )
{
    if( x < 1 || y < 1 || x > n || y > m )
        return false;

    if( pers[x][y] != 0 )
        return false;

    if( dragoni[x][y] - 1 < mid )
        return false;

    return true;
}

void eliberare_drum()
{
    for( int i = 1; i <= n; i++ )
        for( int j = 1; j <= m; j++ )
            if( pers[i][j] != -1 )
                pers[i][j] = 0;
}

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

    for( int i = 1; i <= n; i++ )
        for( int j = 1; j <= m; j++ )
        {
            in>>ch;

            switch( ch )
            {
                case '*': dragoni[i][j] = pers[i][j] = -1; break;
                case 'D': dragoni[i][j] = 1;
                          drag.push( make_pair(i, j) );
                          break;
                case 'I': sx = i;
                          sy = j;
                          pers[i][j] = 1;
                          break;
                case 'O': fx = i;
                          fy = j;
                          break;

            }
        }

    lee( drag, dragoni, ok1 );

    st = 1;

    //af( dragoni );

    dr = max( n, m );

    while( st <= dr )
    {
        mid = (st + dr)/2;

        c.push( make_pair(sx, sy) );
        lee( c, pers, ok2 );

        if( pers[fx][fy] > 0 )
            st = mid + 1;
        else
            dr = mid - 1;

        eliberare_drum();

    }

    if( dr > 0 )
        out<<dr;
    else
        out<<-1;

    return 0;
}