Cod sursa(job #2945547)

Utilizator AnSeDraAndrei Sebastian Dragulescu AnSeDra Data 23 noiembrie 2022 21:22:06
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.08 kb
#include <fstream>
#include <queue>

using namespace std;

#define Nmax 1000

int v[Nmax][Nmax];
int distantaDragon[Nmax][Nmax], pasi[Nmax][Nmax];
queue<pair<int, int>> q;
pair<int, int> pozStart, pozFinish;
int m, n;

bool sePoate(int poz)
{
    ///vedem daca exista un drum care sa aiba distanta minima fata de dragoni >= poz

    int i, j, a, b;

    for(i = 0; i < m; i++)
    {
        for(j = 0; j < n; j++)
        {
            pasi[i][j] = -1;
        }
    }

    pasi[pozStart.first][pozStart.second] = 0;
    q.push(pozStart);

    while(!q.empty())
    {
        a = q.front().first;
        b = q.front().second;
        q.pop();

        if(v[a][b] == 1 || distantaDragon[a][b] < poz)
        {
            continue;
        }

        ///sus
        if(a > 0 && v[a - 1][b] == 0 && pasi[a - 1][b] == -1 && distantaDragon[a - 1][b] >= poz)
        {
            pasi[a - 1][b] = pasi[a][b] + 1;
            q.push({a - 1, b});
        }

        ///jos
        if(a < m - 1 && v[a + 1][b] == 0 && pasi[a + 1][b] == -1 && distantaDragon[a + 1][b] >= poz)
        {
            pasi[a + 1][b] = pasi[a][b] + 1;
            q.push({a + 1, b});
        }

        ///stanga
        if(b > 0 && v[a][b - 1] == 0 && pasi[a][b - 1] == -1 && distantaDragon[a][b - 1] >= poz)
        {
            pasi[a][b - 1] = pasi[a][b] + 1;
            q.push({a, b - 1});
        }

        ///dreapta
        if(b < n - 1 && v[a][b + 1] == 0 && pasi[a][b + 1] == -1 && distantaDragon[a][b + 1] >= poz)
        {
            pasi[a][b + 1] = pasi[a][b] + 1;
            q.push({a, b + 1});
        }
    }

    if(pasi[pozFinish.first][pozFinish.second] > -1)
    {
        return 1;
    }

    return 0;
}

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

    int i, j, a, b, l, r, mid, sol;
    char c;

    fin >> m >> n;

    for(i = 0; i < m; i++)
    {
        for(j = 0; j < n; j++)
        {
            fin >> c;
            distantaDragon[i][j] = -1;

            if(c == '.')
            {
                v[i][j] = 0;
            }
            else if(c == '*')
            {
                v[i][j] = 1;
            }
            else if(c == 'D')
            {
                v[i][j] = 0;
                distantaDragon[i][j] = 0;
                q.push({i, j});
            }
            else if(c == 'I')
            {
                v[i][j] = 0;
                pozStart = {i, j};
            }
            else if(c == 'O')
            {
                v[i][j] = 0;
                pozFinish = {i, j};
            }
        }
    }

    ///Lee extins pentru a afla distanta pana la cel mai apropiat dragon
    while(!q.empty())
    {
        a = q.front().first;
        b = q.front().second;
        q.pop();

        if(v[a][b] == 1)
        {
            continue;
        }

        ///sus
        if(a > 0 && v[a - 1][b] == 0 && distantaDragon[a - 1][b] == -1)
        {
            distantaDragon[a - 1][b] = distantaDragon[a][b] + 1;
            q.push({a - 1, b});
        }

        ///jos
        if(a < m - 1 && v[a + 1][b] == 0 && distantaDragon[a + 1][b] == -1)
        {
            distantaDragon[a + 1][b] = distantaDragon[a][b] + 1;
            q.push({a + 1, b});
        }

        ///stanga
        if(b > 0 && v[a][b - 1] == 0 && distantaDragon[a][b - 1] == -1)
        {
            distantaDragon[a][b - 1] = distantaDragon[a][b] + 1;
            q.push({a, b - 1});
        }

        ///dreapta
        if(b < n - 1 && v[a][b + 1] == 0 && distantaDragon[a][b + 1] == -1)
        {
            distantaDragon[a][b + 1] = distantaDragon[a][b] + 1;
            q.push({a, b + 1});
        }
    }

    ///cautam binar solutia minima
    sol = -1;
    l = 1;
    r = Nmax * Nmax;
    while(l <= r)
    {
        mid = (l + r) / 2;

        if(sePoate(mid))
        {
            sol = mid;
            l = mid + 1;
        }
        else
        {
            r = mid - 1;
        }

    }

    fout << sol;

    return 0;
}