Cod sursa(job #2792580)

Utilizator Stefan_GhinescuGhinescu Stefan-George Stefan_Ghinescu Data 1 noiembrie 2021 22:33:07
Problema Barbar Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.18 kb
#include <fstream>
#include <queue>

using namespace std;

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

const int NMAX = 1000;

int r, c, istart, jstart, ifin, jfin, mat[NMAX + 5][NMAX + 5], matDrake[NMAX + 5][NMAX + 5], matCopy[NMAX + 5][NMAX + 5];

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

struct poz
{
    int linie, coloana;
};

queue <poz> drakes;

bool inb(int a, int b)
{
    return -1 < a && a < r && -1 < b && b < c;
}

void leeDrakes()
{
    while(!drakes.empty())
    {
        int x = drakes.front().linie;
        int y = drakes.front().coloana;
        for (int k = 0; k < 4; ++k)
        {
            int xx = x + dx[k];
            int yy = y + dy[k];
            if (inb(xx, yy) && !matDrake[xx][yy])
            {
                matDrake[xx][yy] = matDrake[x][y] + 1;
                drakes.push({xx, yy});
            }
        }
        drakes.pop();
    }
}

void cpy()
{
    for (int i = 0; i < r; ++i)
    {
        for (int j = 0; j < c; ++j)
        {
            mat[i][j] = matCopy[i][j];
        }
    }
}

bool f(int idk)
{
    queue <poz> q;
    q.push({istart, jstart});
    while(!q.empty())
        {
        int xx = q.front().linie;
        int yy = q.front().coloana;
        for (int k = 0; k < 4; ++k)
        {
            int X = xx + dx[k];
            int Y = yy + dy[k];
            if (inb(X, Y) && mat[X][Y] == 0 && matDrake[X][Y] >= idk)
            {
                mat[X][Y] = mat[xx][yy] + 1;
                q.push({X, Y});
            }
        }
        q.pop();
    }
    return mat[ifin][jfin] > 0;
}

int bs()
{
    int r = 0, pas = (1 << 12), maxi = min(matDrake[istart][jstart], matDrake[ifin][jfin]);
    while (pas)
    {
        if (r + pas < maxi && f(r + pas))
        {
            r += pas;
        }
        cpy();
        pas >>= 1;
    }
    if (r == 0)
        return -1;
    return r;
}

int main()
{
    int i, j;
    fin >> r >> c;
    char ch;
    for (i = 0; i < r; ++i)
    {
        for (j = 0; j < c; ++j)
        {
            fin >> ch;
            if (ch == '.')
            {
                mat[i][j] = matCopy[i][j] = 0;
                matDrake[i][j] = 0;
            }
            else if (ch == '*')
            {
                mat[i][j] = matCopy[i][j] = -1;
                matDrake[i][j] = -1;
            }
            else if (ch == 'D')
            {
                mat[i][j] = matCopy[i][j] = -1;
                matDrake[i][j] = 0;
                drakes.push({i, j});
            }
            else if (ch == 'I')
            {
                mat[i][j] = matCopy[i][j] = 0;
                matDrake[i][j] = 0;
                istart = i;
                jstart = j;
            }
            else if (ch == 'O')
            {
                mat[i][j] = matCopy[i][j] = 0;
                matDrake[i][j] = 0;
                ifin = i;
                jfin = j;
            }
        }
    }
    leeDrakes();
    fout << bs();
    return 0;
}

/**
10 10
..........
.I....D...
..........
..D...D...
.*........
D*........
*...D.....
..****....
...O......
..........
*/