Cod sursa(job #2951681)

Utilizator Razvan48Capatina Razvan Nicolae Razvan48 Data 6 decembrie 2022 22:33:14
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.44 kb
#include <fstream>
#include <queue>

using namespace std;

const int NMAX = 1000;
const int MMAX = 1000;

const int INF = NMAX * MMAX;

int distDragoni[1 + NMAX + 1][1 + NMAX + 1];
int mat[1 + NMAX + 1][1 + MMAX + 1];

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

queue<pair<int, int>> q;

pair<int, int> inceput;
pair<int, int> sfarsit;

void leeDragoni()
{
    while (!q.empty())
    {
        int x = q.front().first;
        int y = q.front().second;

        q.pop();

        for (int i = 0; i < 4; i++)
        {
            int newX = x + dx[i];
            int newY = y + dy[i];

            if (distDragoni[newX][newY] == 0)
            {
                distDragoni[newX][newY] = distDragoni[x][y] + 1;
                q.emplace(newX, newY);
            }
        }
    }
}

bool existaDrum(int distMinima)
{
    while (!q.empty())
        q.pop();

    mat[inceput.first][inceput.second] = distMinima;
    q.emplace(inceput);

    while (!q.empty())
    {
        int x = q.front().first;
        int y = q.front().second;

        q.pop();

        if (sfarsit.first == x && sfarsit.second == y)
            return true;

        for (int i = 0; i < 4; i++)
        {
            int newX = x + dx[i];
            int newY = y + dy[i];

            if (mat[newX][newY] != -1 && mat[newX][newY] != distMinima && distDragoni[newX][newY] >= distMinima)
            {
                mat[newX][newY] = distMinima;
                q.emplace(newX, newY);
            }
        }
    }

    return false;
}

int main()
{
    ios_base::sync_with_stdio(false);

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

    int r, c;
    in >> r >> c;

    for (int i = 0; i <= r + 1; i++)
    {
        mat[i][0]             = -1;
        mat[i][c + 1]         = -1;
        distDragoni[i][0]     = -1;
        distDragoni[i][c + 1] = -1;
    }
    for (int j = 0; j <= c + 1; j++)
    {
        mat[0][j]             = -1;
        mat[r + 1][j]         = -1;
        distDragoni[0][j]     = -1;
        distDragoni[r + 1][j] = -1;
    }

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

            if (c == '*')
            {
                mat[i][j]         = -1;
                distDragoni[i][j] = -1;
            }
            else if (c == 'D')
            {
                q.emplace(i, j);
                distDragoni[i][j] = 1;
            }
            else if (c == 'I')
            {
                inceput = make_pair(i, j);
            }
            else if (c == 'O')
            {
                sfarsit = make_pair(i, j);
            }
        }
    }

    leeDragoni();

    for (int i = 1; i <= r; i++)
    {
        for (int j = 1; j <= c; j++)
        {
            if (distDragoni[i][j] == 0)
                distDragoni[i][j] = INF;
            else if (distDragoni[i][j] > 0)
                distDragoni[i][j]--;
        }
    }

    int st = 0;
    int dr = distDragoni[inceput.first][inceput.second];
    int sol = -1;

    while (st <= dr)
    {
        int mij = (st + dr) / 2;

        if (existaDrum(mij))
        {
            sol = mij;
            st = mij + 1;
        }
        else
        {
            dr = mij - 1;
        }
    }

    out << sol << '\n';

    in.close();
    out.close();

    return 0;
}