Cod sursa(job #1366123)

Utilizator blackoddAxinie Razvan blackodd Data 28 februarie 2015 19:54:36
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.21 kb
#include <fstream>
#include <queue>

using namespace std;

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

#define DIM 1001
#define INF 0x3f3f3f3f

int n, m;
char a[DIM][DIM];
int c[DIM][DIM];
bool viz[DIM][DIM];


int ip, jp; // i plecare, j plecare
int is, js; // i sosire,  j sosire
int dmin, dmax;


const int di[] = { -1, 0, 1, 0 };
const int dj[] = {  0, 1, 0, -1};

queue<pair<int,int> >Q;
queue<pair<int,int> >Q2;

void Read();
void Lee();
bool Umple();
bool Ok(int i, int j);
bool OkUmple(int i, int j);
void Binary();
void Refresh();


int main()
{
    Read();
    Lee();
//    for ( int i = 1; i <= n; ++i )
//    {
//        for (int j = 1; j <= m; ++j )
//            if (c[i][j] == INF )
//                fout << "-1 ";
//        else
//            fout << c[i][j] << ' ';
//        fout << '\n';
//    }
    Binary();
    if ( !dmax )
        fout << "-1\n";
    else
        fout << dmax;
    fin.close();
    fout.close();
    return 0;
}

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

void Binary()
{
    int l = 0, r = DIM;

    while ( l <= r )
    {
        int m = (l + r) / 2;

        dmin = m;

        Q2.push({ip,jp});

        if ( Umple())
            l = m + 1, dmax = m;
        else
            r = m -1;
    }
}

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

	return true;
}

bool ok;

bool Umple()
{
    if ( c[ip][jp] < dmin )
        return false;

    Refresh();

    viz[ip][jp] = true;

    while (!Q2.empty())
    {
        int i = Q2.front().first;
        int j = Q2.front().second;
        Q2.pop();
        for ( int d = 0; d < 4; ++d )
        {
            int iv = i + di[d];
            int jv = j + dj[d];
            if ( OkUmple(iv,jv) && !viz[iv][jv] )
            {
                viz[iv][jv] = true;
                Q2.push({iv,jv});
            }
        }
    }
    return viz[is][js];


}

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

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

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

    }
}