Cod sursa(job #3184284)

Utilizator edi482Eduard Vintu edi482 Data 15 decembrie 2023 10:26:25
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.02 kb
#include <bits/stdc++.h>
#define oo 2000000001
using namespace std;

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

queue< pair<int, int> > q;
char a[1003][1003];
int d[1003][1003], n, m, xs, ys, xf, yf;
short dx[] = {0,0,-1,1};
short dy[] = {-1,1,0,0};
bitset<1003> viz[1003];

void Citire()
{
    char s[1003];
    int i, j;
    fin >> n >> m;
    for (i = 1; i <= n; i++)
    {
        fin >> s;
        for (j = 0; j < m; j++)
        {
            if (s[j] == 'I')
            {
                xs = i; ys = j + 1;
                s[j] = '.';
            }
            if (s[j] == 'O')
            {
                xf = i; yf = j + 1;
                s[j] = '.';
            }
            a[i][j + 1] = s[j];
        }
    }
}

void Bordare()
{
    int i, j;
    for (j = 0; j <= m + 1; j++)
        a[0][j] = a[n + 1][j] = '*';
    for (i = 0; i <= n + 1; i++)
        a[i][0] = a[i][m + 1] = '*';
}

void Init()
{
    for(int i = 0; i <= n+1; i++)
        for(int j = 0; j <= m+1; j++)
            d[i][j] = oo;
}

void Lee()
{
    short i, j, x, y, p;
    for(i = 1; i <= n; i++)
        for(j = 1; j <= m; j++)
            if (a[i][j] == 'D')
            {
                d[i][j] = 0;
                q.push({i, j});
            }
    while(!q.empty())
    {
        i = q.front().first;
        j = q.front().second;
        q.pop();
        for(p = 0; p < 4; p++)
        {
            x = i + dx[p];
            y = j + dy[p];
            if(a[x][y] != '*' && d[x][y] > 1 + d[i][j])
            {
                d[x][y] = d[i][j] + 1;
                q.push({x, y});
            }
        }
    }
    /**
    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= m; j++)
            if (d[i][j] == oo) fout << "X ";
            else fout << d[i][j] << " ";
        fout << "\n";
    }
    */
}

/// facem fill din pozitia de start si
/// vizitam toate pozitiile accesibile d[i][j]
/// cu d[i][j] < oo
void Fill(int xs, int ys, int val)
{
    int i, j, p, x, y;
    stack< pair<int, int> > st;
    for (i = 1; i <= n; i++)
        viz[i].reset();
    st.push({xs, ys});
    viz[xs][ys] = 1;
    while (!st.empty())
    {
        i = st.top().first;
        j = st.top().second;
        st.pop();
        for (p = 0; p < 4; p++)
        {
            x = i + dx[p];
            y = j + dy[p];
            if (d[x][y] < oo && viz[x][y] == 0
                && d[x][y] >= val)
            {
                viz[x][y] = 1;
                st.push({x, y});
            }
        }
    }
}

void Rezolvare()
{
    int st, dr, val, mij;
    st = 1; dr = val = d[xs][ys];
    val = -1;
    while (st <= dr)
    {
        mij = (st + dr) / 2;
        Fill(xs, ys, mij);
        if (viz[xf][yf] == 1)
        {
            val = mij;
            st = mij + 1;
        }
        else dr = mij - 1;
    }
    fout << val << "\n";
}

int main()
{
    Citire();
    Bordare();
    Init();
    Lee();
    Rezolvare();
    return 0;
}