Cod sursa(job #2778486)

Utilizator andreimocianAndrei Mocian andreimocian Data 1 octombrie 2021 15:21:45
Problema Barbar Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.98 kb
#include <iostream>
#include <fstream>
#include <queue>

using namespace std;

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

const int NMAX = 1005;
int n, m, sl, sc, fl, fc;
char a[NMAX][NMAX];
int s[NMAX][NMAX], viz[NMAX][NMAX];
queue < pair < int, int > > Q;
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};

void citire()
{
    fin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            fin >> a[i][j];
            if(a[i][j] == 'D')
            {
                s[i][j] = 1;
                viz[i][j] = -2;
                Q.push(make_pair(i,j));
            }
            else if(a[i][j] == 'I')
            {
                sl = i;
                sc = j;
            }
            else if(a[i][j] == 'O')
            {
                fl = i;
                fc = j;
            }
            else if(a[i][j] == '*')
            {
                s[i][j] = -1;
                viz[i][j] = -1;
            }
        }
    }
}

bool ok(int i, int j)
{
   return(1 <= i && i <= n && 1 <= j && j <= m );
}

void LeeDragoni()
{
    while(!Q.empty())
    {
        int i = Q.front().first;
        int j = Q.front().second;
        Q.pop();
        for(int dir = 0; dir < 4; dir++)
        {
            int i_next = i + dx[dir];
            int j_next = j + dy[dir];
            if(ok(i_next, j_next) && (a[i_next][j_next] == '.' || a[i_next][j_next] == 'O') && s[i_next][j_next] == 0)
            {
                s[i_next][j_next] = 1 + s[i][j];
                Q.push(make_pair(i_next, j_next));
            }
        }
    }
}

bool Lee2(int mij)
{
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            viz[i][j] = 0;
        }
    }
    viz[sl][sc] = 1;
    Q.push(make_pair(sl,sc));
    while(!Q.empty())
    {
        int i = Q.front().first;
        int j = Q.front().second;
        Q.pop();
        for(int dir = 0; dir < 4; dir++)
        {
            int i_next = i + dx[dir];
            int j_next = j + dy[dir];
            if(ok(i_next, j_next) && (a[i_next][j_next] == '.' || a[i_next][j_next] == 'O') && viz[i_next][j_next] == 0 && s[i_next][j_next] >= mij)
            {
                viz[i_next][j_next] = 1 + viz[i][j];
                Q.push(make_pair(i_next, j_next));
            }
        }
    }
    if(viz[fl][fc] == 0)
    {
        return false;
    }
    return true;
}

int cautare_binara(int st, int dr)
{
    int sol = -1;
    while(st <= dr)
    {
        int mij = (st + dr) / 2;
        if(Lee2(mij))
        {
            sol = mij;
            st = mij + 1;
        }
        else
        {
            dr = mij - 1;
        }
    }
    return sol;
}

int main()
{
    citire();
    LeeDragoni();
    int rez = cautare_binara(1,n*m);
    if(rez)
    {
        fout << rez - 1 << "\n";
    }
    else
    {
        fout << -1 << "\n";
    }
    return 0;
}