Cod sursa(job #1366365)

Utilizator mariapascuMaria Pascu mariapascu Data 28 februarie 2015 23:30:26
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.77 kb
#include <fstream>
#include <queue>
using namespace std;

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

const int DIM = 1001, INF = 0x3f3f3f3f;
const int di[] = { -1, 0, 1, 0},
          dj[] = { 0, 1, 0, -1};
int n, m;
char a[DIM][DIM];
int dr[DIM][DIM], ip, jp, is, js;
int dmin, dmax = -1;
bool c[DIM][DIM];
queue<pair<int, int> > Q, W;

void Read();
void LeeDragon();
bool OKLee(int i, int j);
void Cautare();
bool Path();
bool OK(int i, int j);
void Refresh();

int main()
{
    Read();
    LeeDragon();
    Cautare();
    fout << dmax;
    fin.close();
    fout.close();
    return 0;
}

void Cautare()
{
    int l = 0, r = DIM, m;
    while ( l <= r )
    {
        Refresh();
        m = (l + r) / 2;
        dmin = m;
        W.push({ip, jp});
        if ( Path() )
            l = m + 1, dmax = m;
        else
            r = m - 1;
    }
}

bool Path()
{
    if ( dr[ip][jp] < dmin ) return false;
    int i, j, iv, jv;
    c[ip][jp] = true;
    while ( !W.empty() )
    {
        i = W.front().first;
        j = W.front().second;
        W.pop();
        for ( int d= 0; d < 4; d++ )
        {
            iv = i + di[d];
            jv = j + dj[d];
            if ( OK(iv, jv) && c[iv][jv] == false )
            {
                c[iv][jv] = true;
                W.push({iv, jv});
            }
        }
    }
    return c[is][js];
}

bool OK(int i, int j)
{
    if ( i < 1 || i > n || j < 1 || j > m ) return false;
    if ( a[i][j] == '*' ) return false;
    if ( dr[i][j] < dmin ) return false;
    return true;
}

void Refresh()
{
    for ( int i = 1; i <= n; i++ )
        for ( int j = 1; j <= n; j++ )
            c[i][j] = false;
}

void LeeDragon()
{
    int i, j, iv, jv;
    while ( !Q.empty() )
    {
        i = Q.front().first;
        j = Q.front().second;
        Q.pop();
        for ( int d = 0; d < 4; d++ )
        {
            iv = i + di[d];
            jv = j + dj[d];
            if ( OKLee(iv, jv) && dr[i][j] + 1 < dr[iv][jv] )
            {
                dr[iv][jv] = dr[i][j] + 1;
                Q.push({iv, jv});
            }
        }
    }
}

bool OKLee(int i, int j)
{
    if ( i < 1 || i > n || j < 1 || j > m ) return false;
    if ( a[i][j] == '*' ) return false;
    return true;
}

void Read()
{
    fin >> n >> m;
    for ( int i = 1; i <= n; i++ )
        for ( int j = 1; j <= m; j++ )
        {
            fin >> a[i][j];
            dr[i][j] = INF;
            if ( a[i][j] == 'I' )
                ip = i, jp = j;
            if ( a[i][j] == 'O' )
                is = i, js = j;
            if ( a[i][j] == 'D' )
            {
                Q.push({i, j});
                dr[i][j] = 0;
            }
        }
}