Cod sursa(job #2683439)

Utilizator pregoliStana Andrei pregoli Data 11 decembrie 2020 13:03:06
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.92 kb
#include <bits/stdc++.h>
#define newline '\n'
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
///************************

const int NMAX = 1005;
int n, m;
char a[NMAX][NMAX];
int dis[NMAX][NMAX];
bool vis[NMAX][NMAX];

int startI, startJ, stopI, stopJ;
queue<pair<int, int>> q;
const short di[] = {-1, 0, 1, 0}, dj[] = {0, 1, 0, -1}, nd = 4;

void read()
{
    fin >> n >> m;

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            dis[i][j] = INT_MAX;

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
        {
            fin >> a[i][j];
            if (a[i][j] == 'D')
            {
                q.push(make_pair(i, j));
                dis[i][j] = 0;
            }
            else if (a[i][j] == 'I')
            {
                startI = i;
                startJ = j;
            }
            else if (a[i][j] == 'O')
            {
                stopI = i;
                stopJ = j;
            }
        }

}

bool isInside(int i, int j)
{
    if (!i || !j || i > n || j > m)
        return false;
    return true;
}

void Fill()
{
    while (!q.empty())
    {
        int i = q.front().first;
        int j = q.front().second;
        q.pop();

        for (int dir = 0; dir < nd; dir++)
        {
            int nextI = i + di[dir];
            int nextJ = j + dj[dir];
            if (isInside(nextI, nextJ) && a[nextI][nextJ] != '*' && dis[i][j] + 1 < dis[nextI][nextJ])
            {
                dis[nextI][nextJ] = dis[i][j] + 1;
                q.push(make_pair(nextI, nextJ));
            }
        }

    }
}

bool Check(int i, int j, int x)
{
    queue<pair<int, int>> fq;
    vector<vector<bool>> vis(n + 3, vector<bool>(m + 3, false));
    vis[i][j] = true;
    fq.push(make_pair(i, j));

    if (dis[i][j] < x)
        return false;//*/

    while (!fq.empty())
    {
        i = fq.front().first;
        j = fq.front().second;
        fq.pop();

        for (int dir = 0; dir < nd; dir++)
        {
            int nextI = i + di[dir];
            int nextJ = j + dj[dir];
            if (isInside(nextI, nextJ) && a[nextI][nextJ] != '*' && !vis[nextI][nextJ] && x <= dis[nextI][nextJ])
            {
                vis[nextI][nextJ] = true;
                fq.push(make_pair(nextI, nextJ));
                if (nextI == stopI && nextJ == stopJ)
                    return true;
            }
        }
    }
    return false;
}

inline void Solve()
{
    Fill();

    int ans = -1;
    int l = 0, r = n * m;
    while (l <= r)
    {
        int mid = (l + r) / 2;
        bool ok = Check(startI, startJ, mid);
        if (ok)
        {
            ans = mid;
            l = mid + 1;
        }
        else
            r = mid - 1;
    }//*/
    fout << ans;
}

int main()
{
    read();
    Solve();
    fout.close();
    return 0;
}