Cod sursa(job #2532496)

Utilizator PetrescuAlexandru Petrescu Petrescu Data 27 ianuarie 2020 21:21:33
Problema Barbar Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.49 kb
#include <fstream>
#include <cstdlib>
#include <iostream>
#define MAX 1005
#define INF 2e9

using namespace std;

int sol = -1;
int r, c, ir, ic, sr, sc, in, sf = -1;
char mat[MAX][MAX];
int dragonsDist[MAX][MAX], youDist[MAX][MAX];
const char dirlin[] = {-1, 0, 1, 0}, dircol[] = {0, 1, 0, -1};
struct
{
    int x;
    int y;
}coada[MAX * MAX];

void initialization()
{
    int i, j;

    for(i = 1; i <= r; i++)
        for(j = 1; j <= c; j++)
            dragonsDist[i][j] = INF;
}

bool verificareDragons(int lin, int col)
{
    if(mat[lin][col] == '.')
        if(dragonsDist[lin][col] > dragonsDist[coada[in].x][coada[in].y] + 1)
            return true;

    return false;
}

bool verificareYou(int lin, int col, int dist)
{
    if(mat[lin][col] != 'D' && mat[lin][col] != '*' && mat[lin][col] != 'I')
        if(!youDist[lin][col] && dragonsDist[lin][col] >= dist)
            return true;

    return false;
}

void curatareYouDist()
{
    int i, j;

    for(i = 1; i <= r; i++)
        for(j = 1; j <= c; j++)
            youDist[i][j] = 0;

    in = sf = 0;
}

void DragonsLee()
{
    int i, j;

    while(in <= sf)
    {
        for(i = 0; i < 4; i++)
        {
            int lin = coada[in].x + dirlin[i];
            int col = coada[in].y + dircol[i];

            if(verificareDragons(lin, col))
            {
                dragonsDist[lin][col] = dragonsDist[coada[in].x][coada[in].y] + 1;

                sf++;
                coada[sf].x = lin;
                coada[sf].y = col;
            }
        }

        in++;
    }
}

bool YouLee(int dist)
{
    int i, j;
    bool semafor = false;

    coada[in].x = ir;
    coada[in].y = ic;

    while(in <= sf && !semafor)
    {
        for(i = 0; i < 4; i++)
        {
            int lin = coada[in].x + dirlin[i];
            int col = coada[in].y + dircol[i];

            if(verificareYou(lin, col, dist))
            {
                youDist[lin][col] = youDist[coada[in].x][coada[in].y] + 1;

                sf++;
                coada[sf].x = lin;
                coada[sf].y = col;
            }
        }

        in++;

        if(coada[in].x == sr && coada[in].y == sc)semafor = true;
    }

    curatareYouDist();

    return semafor;
}
int main()
{
    int i, j;
    int st, dr;

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

    fin >> r >> c;

    fin.getline(mat[0], MAX);

    for(i = 1; i <= r; i++)
        fin.getline(mat[i] + 1, MAX);

    for(j = 0; j <= c + 1; j++)mat[0][j] = mat[r + 1][j] = '*';
    for(i = 0; i <= r + 1; i++)mat[i][0] = mat[i][c + 1] = '*';

    initialization();

    for(i = 1; i <= r; i++)
        for(j = 1; j <= c; j++)
        {
            if(mat[i][j] == 'D')
            {
                sf++;

                coada[sf].x = i;
                coada[sf].y = j;

                dragonsDist[i][j] = 0;
            }
            else if(mat[i][j] == 'I')
            {
                ir = i;
                ic = j;
            }
            else if(mat[i][j] == 'O')
            {
                sr = i;
                sc = j;
            }
        }

    DragonsLee();

    in = sf = 0;

    st = 1;
    dr = MAX * MAX;

    while(st <= dr)
    {
        int mij = (st + dr) >> 1;

        if(YouLee(mij))
        {
            sol = mij;
            st = mij + 1;
        }
        else dr = mij - 1;
    }

    fout << sol;

    return 0;
}