Cod sursa(job #3140561)

Utilizator SSKMFSS KMF SSKMF Data 7 iulie 2023 09:45:31
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.61 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

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

const short directie[2][4] = {{-1 , 0 , 1 , 0} , {0 , 1 , 0 , -1}};
int linii , coloane , harta[1001][1001];
vector < pair <int , int> > dragoni;
pair <int , int> inceput , sfarsit;

bool Inside (const int linie , const int coloana)
{
    return 1 <= linie && linie <= linii && 1 <= coloana && coloana <= coloane;
}

int CautareBinara (int stanga , int dreapta)
{
    int limita = -1;
    while (stanga <= dreapta)
    {
        int mijloc = (stanga + dreapta) >> 1;
        queue < pair <int , int> > coordonate;
        for (auto locatie : dragoni) {
            harta[locatie.first][locatie.second] = mijloc;
            coordonate.push(locatie);
        }

        while (!coordonate.empty())
        {
            const int linie_1 = coordonate.front().first , coloana_1 = coordonate.front().second;
            if (harta[linie_1][coloana_1] > 1)
                for (int indice = 0 ; indice < 4 ; indice++)
                {
                    const int linie_2 = linie_1 + directie[0][indice] , coloana_2 = coloana_1 + directie[1][indice];
                    if (Inside(linie_2 , coloana_2) && !harta[linie_2][coloana_2]) {
                        harta[linie_2][coloana_2] = harta[linie_1][coloana_1] - 1;
                        coordonate.push(make_pair(linie_2 , coloana_2));
                    }
                }

            coordonate.pop();
        }

        if (harta[inceput.first][inceput.second] || harta[sfarsit.first][sfarsit.second])
            dreapta = mijloc - 1;
        else
        {
            queue < pair <int , int> > coordonate;
            coordonate.push(inceput);
            while (!coordonate.empty())
            {
                const int linie_1 = coordonate.front().first , coloana_1 = coordonate.front().second;
                for (int indice = 0 ; indice < 4 ; indice++)
                {
                    const int linie_2 = linie_1 + directie[0][indice] , coloana_2 = coloana_1 + directie[1][indice];
                    if (Inside(linie_2 , coloana_2) && !harta[linie_2][coloana_2]) {
                        coordonate.push(make_pair(linie_2 , coloana_2));
                        harta[linie_2][coloana_2] = 1;
                    }
                }

                coordonate.pop();
            }

            if (harta[sfarsit.first][sfarsit.second])
                stanga = mijloc + 1 , limita = mijloc;
            else
                dreapta = mijloc - 1;
        }

        for (int linie = 1 ; linie <= linii ; linie++)
            for (int coloana = 1 ; coloana <= coloane ; coloana++)
                if (harta[linie][coloana] > 0)
                    harta[linie][coloana] = 0;
    }

    return limita;
}

int main ()
{
    cin >> linii >> coloane;

    char sir[1001];
    for (int linie = 1 ; linie <= linii ; linie++)
    {
        cin >> sir;
        for (int coloana = 1 ; coloana <= coloane ; coloana++)
            switch (sir[coloana - 1])
            {
                case 'I': inceput.first = linie , inceput.second = coloana;
                    break;

                case 'O': sfarsit.first = linie , sfarsit.second = coloana;
                    break;

                case 'D': dragoni.push_back(make_pair(linie , coloana));
                    break;

                case '*': harta[linie][coloana] = -1;
                    break;
            }
    }

    cout << CautareBinara(1 , max(linii , coloane) - 1);
    cout.close(); cin.close();
    return 0;
}