Cod sursa(job #2793055)

Utilizator Stefan_DomuncoStefan Domunco Stefan_Domunco Data 2 noiembrie 2021 19:21:07
Problema Barbar Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.1 kb
///lee din dragoni,apoi caut binar distanta minima maxima si verific cu lee
///O(n*m*log(n*m))
#include <bits/stdc++.h>

using namespace std;

ifstream fin("barbar.in");
ofstream fout("barbar.out");
const int NMAX = 1e3+3;
int mat[NMAX][NMAX], aux[NMAX][NMAX];
bool viz[NMAX][NMAX];
///N E S V
int dirx[] = {-1, 0, 1, 0},
    diry[] = {0, 1, 0, -1};
int n, m, starti, startj;
queue <pair <int, int> >coada;

bool exist(int lin, int col)
{
    if(lin < 1 || lin > n)
        return false;

    if(col < 1 || col > m)
        return false;

    if(viz[lin][col])
        return false;

    if(aux[lin][col] == -1)
        return false;

    return true;
}

void lee()
{
    int lin, col, i;
    while(!coada.empty())
    {
        lin = coada.front().first;
        col = coada.front().second;
        coada.pop();
        for(i = 0; i < 4; ++i)
            if(exist(lin+dirx[i], col+diry[i]))
            {
                viz[lin+dirx[i]][col+diry[i]] = true;
                mat[lin+dirx[i]][col+diry[i]] = mat[lin][col] + 1;
                coada.push({lin+dirx[i], col+diry[i]});
            }
    }
}

void init()
{
    int i, j;
    for(i = 1; i <= n; ++i)
        for(j = 1; j <= m; ++j)
        {
            viz[i][j] = true;
            if(aux[i][j] != -1) aux[i][j] = 0; viz[i][j] = false;
        }

}

void lee_barbar(int &startlin, int &startcol, int lim)
{
    init();
    coada.push({startlin, startcol});
    aux[startlin][startcol] = 1;
    viz[startlin][startcol] = true;
    int lin, col, i;
    while(!coada.empty())
    {
        lin = coada.front().first;
        col = coada.front().second;
        coada.pop();
        for(i = 0; i < 4; ++i)
            if(exist(lin+dirx[i], col+diry[i]) && mat[lin+dirx[i]][col+diry[i]] >= lim)
            {
                viz[lin+dirx[i]][col+diry[i]] = true;
                aux[lin+dirx[i]][col+diry[i]] = aux[lin][col] + 1;
                coada.push({lin+dirx[i], col+diry[i]});
            }
    }
}

int ajuns(int &startlin, int &startcol, int &stoplin, int &stopcol, int mij)
{
    lee_barbar(startlin, startcol, mij);
    return aux[stoplin][stopcol];
}

void bs(int &startlin, int &startcol, int &stoplin, int &stopcol)
{
    int st, dr, mij, sol=0;
    st = 0, dr = 1000*1000;

    while(st <= dr)
    {
        mij = (st+dr) / 2;
        ///daca am solutie caut in dreapta
        if(ajuns(startlin, startcol, stoplin, stopcol, mij) > 0)
            sol = mij, st = mij + 1;
        else dr = mij - 1;
    }
    fout << sol;
}
int main()
{
    char ch;
    int i, j, startlin, startcol, stoplin, stopcol;

    fin >> n >> m;
    for(i = 1; i <= n; ++i)
        for(j = 1; j <= m; ++j)
        {
            fin >> ch, aux[i][j] = mat[i][j] = (ch=='*') ? -1 : 0;
            if(ch == 'D')
                coada.push({i, j}), viz[i][j] = true;
            else if(ch == 'I')
                startlin = i, startcol = j;
            else if(ch == 'O')
                stoplin = i, stopcol = j;
        }

    lee();
    bs(startlin, startcol, stoplin, stopcol);

    return 0;
}