Cod sursa(job #2502384)

Utilizator LeCapataIustinian Serban LeCapata Data 30 noiembrie 2019 19:20:43
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.46 kb
#include <fstream>
#include <queue>
using namespace std;

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

int mat[1010][1010], drag[1010][1010], drum_fin[1010][1010];
int r, c, nr_drag, poz = -1;

int dx[] = { 0,0,1,-1 };
int dy[] = { -1,1,0,0 };


pair<int, int> coord_drag[1000001], coord_start, coord_final;
queue<pair<int, int> > coada;

void init()
{
    for (int i = 1; i <= r; i++)
        for (int j = 1; j <= c; j++)
            drum_fin[i][j] = 0;
}

void afisare(int x[][1010])
{
    for (int i = 1; i <= r; i++)
    {
        for (int j = 1; j <= c; j++)
            out << x[i][j] << " ";
        out << '\n';
    }
    out << '\n';
}

void captusire(int x[][1010])
{
    for (int i = 0; i <= r + 1; i++)
        x[i][0] = x[i][c + 1] = -1;

    for (int j = 0; j <= c + 1; j++)
        x[0][j] = x[r + 1][j] = -1;
}

void alg_Lee()
{
    while (!coada.empty())
    {
        int okx = coada.front().first;
        int oky = coada.front().second;
        coada.pop();

        for (int i = 0; i < 4; i++)
        {
            int x2 = okx + dx[i];
            int y2 = oky + dy[i];

            if ((drag[x2][y2] > drag[okx][oky] + 1 || drag[x2][y2] == 0) && mat[x2][y2] != -1)
            {
                drag[x2][y2] = drag[okx][oky] + 1;
                coada.push(make_pair(x2, y2));
            }
        }
    }
}

int drum(int mij)
{
    init();
    while (!coada.empty())
        coada.pop();
    drum_fin[coord_start.first][coord_start.second] = 1;
    coada.push(coord_start);

    while (!coada.empty())
    {
        int okx = coada.front().first;
        int oky = coada.front().second;
        coada.pop();

        if (okx == coord_final.first && oky == coord_final.second)
            return 1;

        for (int i = 0; i < 4; i++)
        {
            int x2 = okx + dx[i];
            int y2 = oky + dy[i];

            if ((drag[x2][y2] >= mij) && (drum_fin[x2][y2] > drum_fin[okx][oky] + 1 || drum_fin[x2][y2] == 0))
            {
                drum_fin[x2][y2] = drum_fin[okx][oky] + 1;
                coada.push(make_pair(x2, y2));
            }
        }
    }
    return 0;
}

void caut_bin(int st, int dr)
{
    while (st <= dr)
    {
        int mij = (st + dr) / 2;
        if (drum(mij) == 1)
        {
            poz = mij;
            st = mij + 1;
        }
        else dr = mij - 1;
    }
}

int main()
{
    in >> r >> c;
    captusire(drag);
    captusire(drum_fin);

    for (int i = 1; i <= r; i++)
        for (int j = 1; j <= c; j++)
        {
            char x;
            in >> x;

            if (x == '.')
                mat[i][j] = 0;
            else if (x == '*')
                mat[i][j] = -1;
            else if (x == 'D')
            {
                mat[i][j] = -1;
                coord_drag[++nr_drag] = make_pair(i, j);
            }
            else if (x == 'I')
            {
                mat[i][j] = 0;
                coord_start = make_pair(i, j);
            }
            else if (x == 'O')
            {
                mat[i][j] = 0;
                coord_final = make_pair(i, j);
            }
        }

    for (int i = 1; i <= nr_drag; i++)
    {
        coada.push(make_pair(coord_drag[i].first, coord_drag[i].second));
    }

    alg_Lee();

    caut_bin(0, r*c);

    if (poz == 0)
        poz = -1;
    out << poz << "\n";

    in.close();
    out.close();
    return 0;
}