Cod sursa(job #3037815)

Utilizator SSKMFSS KMF SSKMF Data 26 martie 2023 15:11:49
Problema Barbar Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.98 kb
#include <fstream>
#include <utility>
#include <vector>
#include <queue>
using namespace std;

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

short int directie_linie[] = {-1 , 0 , 1 , 0},
        directie_coloana[] = {0 , 1 , 0 , -1};

struct Coordonate {
    int linie , coloana;
} inceput , iesire;

vector < pair <int , int> > dragoni;

int linii , coloane , labirint[101][101];
bool posibil;

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

void Fill (int linie , int coloana , int lungime , int valoare)
{
    if (labirint[linie][coloana] == -2 || labirint[linie][coloana] == valoare)
        return;

    labirint[linie][coloana] = valoare;

    if (lungime > 1)
        for (int indice = 0 ; indice < 4 ; indice++)
            if (Inside(linie , coloana))
                Fill(linie + directie_linie[indice] , coloana + directie_coloana[indice] , lungime - 1 , valoare);
}

void Backtracking (int linie , int coloana)
{
    if (!Inside(linie , coloana) || labirint[linie][coloana])
        return;

    if (linie == iesire.linie && coloana == iesire.coloana)
        posibil = true;

    labirint[linie][coloana] = 1;

    for (int indice = 0 ; indice < 4 && !posibil ; indice++)
        Backtracking(linie + directie_linie[indice] , coloana + directie_coloana[indice]);

    labirint[linie][coloana] = 0;
}

int Distanta_Maxima ()
{
    int stanga = 1 , dreapta = max(linii , coloane) - 1 , distanta_maxima = 1000;
    while (stanga <= dreapta)
    {
        int distanta = (stanga + dreapta) / 2;

        for (auto dragon : dragoni)
            Fill(dragon.first , dragon.second , distanta , -1);

        Backtracking(inceput.linie , inceput.coloana);

        if (posibil)
            stanga = distanta + 1 , distanta_maxima = distanta;
        else
            dreapta = distanta - 1;

        if (stanga <= dreapta)
            for (auto dragon : dragoni)
                Fill(dragon.first , dragon.second , distanta , 0);

        posibil = false;
    }

    if (distanta_maxima == 1000)
        return -1;

    return distanta_maxima;
}

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

    char rand[101];
    for (int linie = 1 ; linie <= linii ; linie++)
    {
        cin >> rand;

        for (int coloana = 0 ; coloana < coloane ; coloana++)
            if (rand[coloana] == 'I')
                inceput.linie = linie , inceput.coloana = coloana + 1;
            else
                if (rand[coloana] == 'O')
                    iesire.linie = linie , iesire.coloana = coloana + 1;
                else
                    if (rand[coloana] == 'D')
                        dragoni.push_back(make_pair(linie , coloana));
                    else
                        if (rand[coloana] == '*')
                            labirint[linie][coloana] = -2;
    }

    cout << Distanta_Maxima();
    cout.close(); cin.close();
    return 0;
}