Cod sursa(job #2824803)

Utilizator Radu_FilipescuFilipescu Radu Radu_Filipescu Data 3 ianuarie 2022 15:30:57
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.36 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 1005;

int N, M;
int mat[NMAX][NMAX];
int l1, c1, l2, c2;
int dl[4] = { 0, -1,  0, 1 };
int dc[4] = { 1,  0, -1, 0 };
vector < pair<int,int> > Drg;
bool vis[NMAX][NMAX];

struct mzg
{
    int L, C;
    int cost, d_min;

    bool operator < ( const mzg & A ) const {
        return cost < A.cost;
    }
};

priority_queue <mzg> PQ;

void Read()
{
    fin >> N >> M;

    string line;

    for( int i = 1; i <= N; ++i ) {
        fin >> line;

        for( int j = 0; j < line.size(); ++j ) {
            if( line[j] == '*' ) mat[i][j + 1] = -1;
            if( line[j] == 'D' ) Drg.push_back( { i, j + 1 } );
            if( line[j] == 'I' ) l1 = i, c1 = j + 1;
            if( line[j] == 'O' ) l2 = i, c2 = j + 1;
        }
    }
}

void Do()
{
    deque < pair<int,int> > Q;

    for( int i = 0; i < Drg.size(); ++i ) {
        Q.push_back( { Drg[i].first, Drg[i].second } );
        mat[ Drg[i].first ][ Drg[i].second ] = 1;
    }

    for( int i = 0; i <= N + 1; ++i )
       mat[i][0] = mat[i][M + 1] = -1;

    for( int j = 0; j <= M + 1; ++j )
       mat[0][j] = mat[N + 1][j] = -1;

    int L, C, lv, cv;
    while( !Q.empty() ) {
        L = Q.front().first;
        C = Q.front().second;

        Q.pop_front();

        for( int i = 0; i < 4; ++i ) {
            lv = L + dl[i];
            cv = C + dc[i];

            if( mat[lv][cv] == 0 ) {
                mat[lv][cv] = mat[L][C] + 1;
                Q.push_back( { lv, cv } );
            }
        }
    }

    vis[l1][c1] = true;
    PQ.push( { l1, c1, mat[l1][c1], mat[l1][c1] } );

    int max_D = 0, dmin;

    while( !PQ.empty() ) {
        L = PQ.top().L;
        C = PQ.top().C;

        dmin = PQ.top().d_min;

        PQ.pop();

        if( L == l2 && C == c2 ) { max_D = max( max_D, dmin ); break; }

        for( int i = 0; i < 4; ++i ) {
            lv = L + dl[i];
            cv = C + dc[i];

            if( mat[lv][cv] > 0 && !vis[lv][cv] )
            {
                vis[lv][cv] = true;
                PQ.push( { lv, cv, mat[lv][cv], min( dmin, mat[lv][cv] ) } );
            }
        }
    }

    fout << max_D - 1 << '\n';
}

int main()
{
    Read();
    Do();

    return 0;
}