Cod sursa(job #3140557)

Utilizator SSKMFSS KMF SSKMF Data 7 iulie 2023 09:35:56
Problema Barbar Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.16 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;
}

void Fill (int linie , int coloana , int lungime , int valoare)
{
    if (!Inside(linie , coloana) || harta[linie][coloana] || !lungime)
        return;

    harta[linie][coloana] = valoare;
    for (int indice = 0 ; indice < 4 ; indice++)
        Fill(linie + directie[0][indice] , coloana + directie[1][indice] , lungime - 1 , valoare);
}

int CautareBinara (int stanga , int dreapta)
{
    int limita = -1;
    while (stanga <= dreapta)
    {
        int mijloc = (stanga + dreapta) >> 1;
        for (auto coordonate : dragoni) {
            Fill(coordonate.first , coordonate.second , mijloc , -1);
            if (harta[inceput.first][inceput.second] || harta[sfarsit.first][sfarsit.second])
                break;
        }

        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++)
                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;
            }
    }

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