Cod sursa(job #2240468)

Utilizator mihailescu_eduardMihailescu Eduard-Florin mihailescu_eduard Data 13 septembrie 2018 15:50:00
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.3 kb
#include <cstdio>
#include <cstring>
#include <queue>

FILE *fin = freopen("barbar.in","r",stdin); FILE *fout = freopen("barbar.out","w",stdout);


static const int NMAX = 1e3 + 5;

/// Vectori de parcurgere
int dx[4] = {0, 1, 0, -1};
int dy[4] = {-1, 0, 1, 0};

/* ------- DATA -------- */
int n, m;
int start_x, start_y;
int end_x, end_y;
char harta[NMAX][NMAX];
int distanteDragoni[NMAX][NMAX];
bool seen[NMAX][NMAX];
std::queue<std::pair<int,int> > dragoni;
/* ------- DATA -------- */

void ReadInput()
{
    scanf("%d%d",&n,&m);
    for(int i = 1; i<= n; ++i)
    {
        scanf("%s",harta[i] + 1);
    }
}

bool Check(int i, int j)
{
    if(i < 1 || i > n || j < 1 || j > m)
        return false;
    if(harta[i][j] == '*')
        return false;
    return true;
}

void ConstructFirstMatrix()
{
    for(int i = 1; i<= n; ++i)
    {
        for(int j =1 ; j<=m; ++j)
        {
            if(harta[i][j] == 'D')
            {
                dragoni.push(std::make_pair(i,j));
            }
            else if(harta[i][j] == 'I')
            {
                start_x = i; start_y = j;
                distanteDragoni[i][j] = -1;
            }
            else if(harta[i][j] == 'O')
            {
                end_x = i; end_y = j;
                distanteDragoni[i][j] = -1;
            }
            else
            {
                distanteDragoni[i][j] = -1;
            }
        }
    }

    while(!dragoni.empty())
    {
        int x = dragoni.front().first;
        int y = dragoni.front().second;
        dragoni.pop();

        for(int i = 0 ; i< 4; ++i)
        {
            int next_x = x + dx[i];
            int next_y = y + dy[i];

            if(Check(next_x, next_y) && distanteDragoni[next_x][next_y] == -1)
            {
                dragoni.push(std::make_pair(next_x,next_y));
                distanteDragoni[next_x][next_y] = distanteDragoni[x][y] + 1;
            }
        }
    }
}

bool Lee(int d)
{
    for(int i = 1; i<= n; ++i)
    {
        for(int j = 1; j<= m; ++j)
        {
            seen[i][j] = false;
        }
    }
    seen[start_x][start_y] = true;
    std::queue<std::pair<int,int> > coada;
    coada.push(std::make_pair(start_x,start_y));
    while(!coada.empty())
    {
        int x = coada.front().first;
        int y = coada.front().second;

        for(int i = 0; i< 4; ++i)
        {
            int next_x = x + dx[i];
            int next_y = y + dy[i];
            if(Check(next_x,next_y) && distanteDragoni[next_x][next_y] >= d && seen[next_x][next_y] == false)
            {
                seen[next_x][next_y] = true;
                if(next_x == end_x && next_y == end_y)
                {
                    return true;
                }
                coada.push(std::make_pair(next_x,next_y));
            }
        }
        coada.pop();
    }
    return false;
}

void Solve()
{
    int pas = 1, k = 0;
    for(; pas <= n + m; pas <<=1);

    for(; pas; pas >>=1)
    {
        if(k + pas <= n + m)
        {
            if(Lee(k+pas))
                k+=pas;
        }
    }
    if(k == 0)
        printf("-1");
    else
        printf("%d",k);
}


int main()
{
    ReadInput();
    ConstructFirstMatrix();
    Solve();

    return 0;

}