Cod sursa(job #2908582)

Utilizator AswVwsACamburu Luca AswVwsA Data 4 iunie 2022 15:59:13
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.68 kb
#include <fstream>
#include <queue>
#include <climits>
using namespace std;

char s[1003][1003];
int d[1003][1003];
int oki[1003][1003];
queue <pair <int, int> > q;
pair <int, int> in, out;

int di[] = {-1, 1, 0, 0};
int dj[] = {0, 0, -1, 1}, n, m;

int cnt = 0;
bool ok(int val)
{
    cnt++;
    oki[in.first][in.second] = cnt;
    queue <pair <int, int> > q1; //sa speram ca e mai rapid ca golirea manuala
    q1.push(in);
    while (!q1.empty())
    {
        pair <int, int> f = q1.front();
        //cout << f.first << " " << f.second << "\n";
        q1.pop();
        for (int i = 0; i < 4; i++)
        {
            int ni = f.first + di[i];
            int nj = f.second + dj[i];
            if (ni >= 1 and ni <= n and nj >= 1 and nj <= m and
                    oki[ni][nj] != cnt and
                    s[ni][nj] != '*' and d[ni][nj] >= val)
            {
                if (ni == out.first and nj == out.second)
                    return 1;
                oki[ni][nj] = cnt;
                q1.push({ni, nj});
            }
        }
    }
    return 0;
}
int main()
{
    ifstream cin("barbar.in");
    ofstream cout("barbar.out");
    int i, j;
    cin >> n >> m;
    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= m; j++)
        {
            cin >> s[i][j];
            d[i][j] = INT_MAX;
            if (s[i][j] == 'D')
            {
                q.push({i, j});
                d[i][j] = 0;
            }
            else if (s[i][j] == 'I')
                in = {i, j};
            else if (s[i][j] == 'O')
                out = {i, j};
        }
    }
    //vad distanta minima fata de dragoni si celelalte patratele
    while (!q.empty())
    {
        pair <int, int> f = q.front();
        q.pop();
        for (int i = 0; i < 4; i++)
        {
            int ni = f.first + di[i];
            int nj = f.second + dj[i];
            if (ni >= 1 and ni <= n and nj >= 1 and nj <= m
                and s[ni][nj] != '*')
            {
                if (d[ni][nj] > d[f.first][f.second] + 1)
                {
                    d[ni][nj] = d[f.first][f.second] + 1;
                    q.push({ni, nj});
                }
            }
        }
    }/*
    cout << "\n\n\n";
    for (i = 1; i <= n; i++, cout << "\n")
        for (j = 1; j <= m; j++)
            cout << d[i][j] << " ";*/
    int med, sol = -1, st = 1, dr = min(d[in.first][in.second], d[out.first][out.second]);
    while (st <= dr)
    {
        med = ((st + dr) >> 1);
        if (ok(med))
        {
            sol = med;
            st = med + 1;
        }
        else
            dr = med - 1;
    }
    cout << sol;
}