Cod sursa(job #3342922)

Utilizator rapidu36Victor Manz rapidu36 Data 26 februarie 2026 10:25:47
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.58 kb
#include <fstream>
#include <cstring>
#include <queue>

using namespace std;

const int N = 1000;
const int ND = 4;
const int DL[ND] = {-1, 0, 1, 0};
const int DC[ND] = {0, -1, 0, 1};

struct punct
{
    int l, c;
};

char aux[N+1];
int nl, nc;
int d[N+1][N+1];
bool a[N+2][N+2];
queue <punct> q;

void _fill(punct x, int dist)
{
    a[x.l][x.c] = true;
    for (int i = 0; i < ND; i++)
    {
        punct y = (punct){x.l + DL[i], x.c + DC[i]};
        if (!a[y.l][y.c] && (d[y.l][y.c] != -2 && d[y.l][y.c] >= dist))
        {
            _fill(y, dist);
        }
    }
}

bool exista_drum(punct x, punct y, int dist)
{
    for (int i = 1; i <= nl; i++)
    {
        a[i][0] = a[i][nc+1] = true;
    }
    for (int j = 1; j <= nc; j++)
    {
        a[0][j] = a[nl+1][j] = true;
    }
    for (int i = 1; i <= nl; i++)
    {
        for (int j = 1; j <= nc; j++)
        {
            a[i][j] = false;
        }
    }
    if (d[x.l][x.c] >= dist)
    {
        _fill(x, dist);
    }
    return a[y.l][y.c];
}

int main()
{
    ifstream in("barbar.in");
    ofstream out("barbar.out");
    punct x_ini, x_fin;
    in >> nl >> nc;
    for (int i = 1; i <= nl; i++)
    {
        in >> aux;
        for (int j = 1; j <= nc; j++)
        {
            d[i][j] = -1;
            if (aux[j-1] == 'D')
            {
                d[i][j] = 0;
                q.push((punct){i, j});
            }
            else if (aux[j-1] == 'I')
            {
                x_ini.l = i;
                x_ini.c = j;
            }
            else if (aux[j-1] == 'O')
            {
                x_fin.l = i;
                x_fin.c = j;
            }
            else if (aux[j-1] == '*')
            {
                d[i][j] = -2;
            }
        }
    }
    ///distantele fata de dragoni
    while (!q.empty())
    {
        punct x = q.front();
        q.pop();
        for (int i = 0; i < ND; i++)
        {
            punct y = (punct){x.l + DL[i], x.c + DC[i]};
            if (d[y.l][y.c] == -1)
            {
                d[y.l][y.c] = 1 + d[x.l][x.c];
                q.push(y);
            }
        }
    }
    ///cautam binar cea mai mica distanta fata de dragoni
    int st = 0, dr = nl * nc, rez = -1;
    while (st <= dr)
    {
        int m = (st + dr) / 2;
        if (exista_drum(x_ini, x_fin, m))
        {
            rez = m;
            st = m + 1;
        }
        else
        {
            dr = m - 1;
        }
    }
    out << rez << "\n";
    in.close();
    out.close();
    return 0;
}