Cod sursa(job #2116351)

Utilizator SpiristulTeribilStefan Vilcu SpiristulTeribil Data 27 ianuarie 2018 15:51:03
Problema Barbar Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.11 kb
#include <fstream>
#include <queue>

using namespace std;

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

struct poz
{
    int l, c ;
} start, stop ;

int dx[]= {-1, 0, 1, 0} ;
int dy[]= {0, 1, 0, -1} ;

int nr[1002][1002] ;
int M[1002][1002] ;
int n, m, st, dr, mij ;
queue <poz>coada ;

void lee()
{
    poz p, q ;
    int lv, cv ;
    while(!coada.empty())
    {
        p = coada.front() ;
        coada.pop() ;
        for(int d = 1 ; d <= 4 ; d++)
        {
            lv = p.l + dx[d] ;
            cv = p.c + dy[d] ;
            if(lv > 0 && lv <= n && cv > 0 && cv <= m)
            {
                if( nr[lv][cv] == 0 )
                {
                    nr[lv][cv] = nr[p.l][p.c] + 1 ;
                    q.l = lv ;
                    q.c = cv ;
                    coada.push(q) ;
                }
            }
        }
    }
}
char ch ;
int main()
{
    cin >> n >> m ;
    for ( int i = 1 ; i <= n ; i++)
    {
        for (int j = 1 ; j <= m ; j++)
        {
            cin >> ch ;
            if (ch == '*')
                nr[i][j] = -1 ;
            else
            {
                if (ch == 'I')
                {
                    start.l = i ;
                    start.c = j ;
                }
                if (ch == 'O')
                {
                    stop.l = i ;
                    stop.c = j ;
                }
                if (ch == 'D')
                {
                    poz q ;
                    q.l = i ;
                    q.c = j ;
                    coada.push(q) ;
                    nr[i][j] = 1 ;
                }
            }
        }
    }
    lee() ;
    st = 1 ;
    dr = max(n, m) ;
    bool sol = 0 ;
    bool gasit = 0 ;
    while (st <= dr)
    {
        mij = (st + dr) / 2 ;
        while(!coada.empty())
            coada.pop() ;
        if(mij > nr[start.l][start.c])
        {
            dr = mij - 1 ;
            continue ;
        }
        else
        {
            poz p, q;
            int lv, cv;
            coada.push(start);
            M[start.l][start.c]= mij ;
            while(!coada.empty() && !gasit)
            {
                p = coada.front() ;
                coada.pop() ;
                for(int d = 1 ; d <= 4 ; d++)
                {
                    lv = p.l + dx[d] ;
                    cv = p.c + dy[d] ;
                    if(lv > 0 && lv <= n && cv > 0 && cv <= m)
                    {
                      if(nr[lv][cv] >= mij && M[lv][cv]!= mij)
                        {
                        M[lv][cv] = mij ;
                        q.l = lv ;
                        q.c = cv ;
                        if(lv == stop.l && cv == stop.c)
                        {
                            gasit = 1 ;
                        }
                        coada.push(q) ;
                        }
                    }
                }
            }
            if(gasit != 0)
            {
                st = mij + 1 ;
                sol = 1 ;
            }
            else
                dr = mij - 1 ;
        }
    }

    if(sol != 0)
        cout << dr - 2 << "\n" ;
    else
        cout << "-1" ;

    return 0;
}