Cod sursa(job #1023645)

Utilizator UnforgivenMihai Catalin Botezatu Unforgiven Data 7 noiembrie 2013 15:16:23
Problema Barbar Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.43 kb
#include <iostream>
#include <fstream>
#include <queue>


const static int MAX_ROWS = 1000;
const static int MAX_COLUMNS = 1000;

using namespace std;

ifstream input("barbar.in");
ofstream output("barbar.out");

char matrice[MAX_ROWS][MAX_COLUMNS];
int distante[MAX_ROWS][MAX_COLUMNS];
bool select[MAX_ROWS][MAX_COLUMNS];

int N , M;
int distanta_max = 0;
queue<pair<int, int> > coada;
pair<int, int> start_pozitie;
pair<int, int> sosire_pozitie;

bool is_in_matrix(const int &x , const int &y)
{
    return (x >= 0 && y >= 0 && x < N && y < M);
}

void BFS()
{
    int dx[] = {0 , 0 , 1 , -1};
    int dy[] = {1 , -1 , 0 , 0};
    int new_x , new_y;

    while (!coada.empty())
    {
        pair<int, int> celula = coada.front();
        coada.pop();
        for (int i = 0; i < 4; i++)
        {
            int new_x = celula.first + dx[i];
            int new_y = celula.second + dy[i];
            if (is_in_matrix(new_x , new_y) && matrice[new_x][new_y] != 'D' && matrice[new_x][new_y] != '*' && distante[new_x][new_y] == 0)
            {
                distante[new_x][new_y] = distante[celula.first][celula.second] + 1;
                distanta_max = max(distanta_max , distante[new_x][new_y]);
                coada.push(pair<int, int>(new_x, new_y));
            }
        }
    }
}

void Final_BFS()
{
    queue<pair<int, int> > locked;
    queue<pair<int, int> > queue;
    int dx[] = {0 , 0 , 1 , -1};
    int dy[] = {1 , -1 , 0 , 0};
    int new_x , new_y;
    bool is_locked = true;

    locked.push(start_pozitie);

    while (!locked.empty() && distanta_max > 0)
    {
        while (!locked.empty())
        {
            pair<int, int> celula = locked.front();
            locked.pop();
            queue.push(celula);
        }

        while (!queue.empty())
        {
            pair<int, int> celula = queue.front();
            queue.pop();
            is_locked = true;

            for (int i = 0 ; i < 4 ; i++)
            {
                int new_x = celula.first + dx[i];
                int new_y = celula.second + dy[i];
                if (is_in_matrix(new_x, new_y) && !select[new_x][new_y] && distante[new_x][new_y] >= distanta_max && matrice[new_x][new_y] != '*' && matrice[new_x][new_y] != 'D')
                {
                    select[new_x][new_y] = true;
                    queue.push(pair<int, int>(new_x, new_y));
                    is_locked = false;
                }
            }

            if (is_locked)
                locked.push(pair<int, int>(celula.first, celula.second));
        }

        if (select[sosire_pozitie.first][sosire_pozitie.second])
            return;

        if (!locked.empty())
        {
            distanta_max--;
        }

    }
}


int main(int argc , char *argv[])
{
    input >> N >> M;
    for (int i = 0; i < N; i++)
        for (int j = 0; j < M; j++)
        {
            input >> matrice[i][j];
            if (matrice[i][j] == 'D')
                coada.push(pair<int, int>(i, j));
            if (matrice[i][j] == 'I')
                start_pozitie = pair<int, int>(i, j);
            if (matrice[i][j] == 'O')
                sosire_pozitie = pair<int, int>(i, j);

        }

    BFS();
    Final_BFS();
    if (distanta_max)
    {
        output << distanta_max;
    }
    else
    {
        output << "-1";
    }

    input.close();
    output.close();

    return 0;
}