Cod sursa(job #3002235)

Utilizator rapidu36Victor Manz rapidu36 Data 14 martie 2023 15:50:18
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.78 kb
#include <fstream>
#include <queue>

using namespace std;

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

struct poz
{
    int l, c;
};

queue <poz> q;

char a[N+2][N+2];
int d[N+2][N+2];
bool viz[N+2][N+2];
poz x_i, x_f;
int nl, nc;

void distante_dragoni()
{
    while (!q.empty())
    {
        poz x = q.front();
        q.pop();
        for (int i = 0; i < 4; i++)
        {
            poz y = (poz){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);
            }
        }
    }
}

bool exista_drum(int d_min)
{
    for (int i = 1; i <= nl; i++)
    {
        for (int j = 1; j <= nc; j++)
        {
            viz[i][j] = false;
            if (d[i][j] < d_min)
            {
                viz[i][j] = true;
            }
        }
    }
    queue <poz> q;
    if (viz[x_i.l][x_i.c])
    {
        return false;
    }
    q.push(x_i);
    viz[x_i.l][x_i.c] = true;
    while (!q.empty())
    {
        poz x = q.front();
        q.pop();
        for (int i = 0; i < 4; i++)
        {
            poz y = (poz){x.l + DL[i], x.c + DC[i]};
            if (!viz[y.l][y.c] && a[y.l][y.c] == '.')
            {
                q.push(y);
                viz[y.l][y.c] = true;
            }
            if (y.l == x_f.l && y.c == x_f.c)
            {
                return true;
            }
        }
    }
    return false;
}

int caut_dist_max()
{
    int st = 0, dr = N*N, rez = -1;
    while (st <= dr)
    {
        int m = (st + dr) / 2;
        if (exista_drum(m))
        {
            rez = m;
            st = m + 1;
        }
        else
        {
            dr = m - 1;
        }
    }
    return rez;
}

int main()
{
    ifstream in("barbar.in");
    ofstream out("barbar.out");
    in >> nl >> nc;
    for (int i = 1; i <= nl; i++)
    {
        in >> (1 + a[i]);
        for (int j = 1; j <= nc; j++)
        {
            if (a[i][j] == '.')
            {
                d[i][j] = -1;
            }
            else if (a[i][j] == '*')
            {
                d[i][j] = -2;
            }
            else if (a[i][j] == 'I')
            {
                d[i][j] = -1;
                x_i = (poz){i, j};
                a[i][j] = '.';
            }
            else if (a[i][j] == 'O')
            {
                d[i][j] = -1;
                x_f = (poz){i, j};
                a[i][j] = '.';
            }
            else
            {
                d[i][j] = 0;
                q.push((poz){i, j});
            }
        }
    }
    distante_dragoni();
    out << caut_dist_max();
    in.close();
    out.close();
    return 0;
}