Cod sursa(job #2460866)

Utilizator dey44andIoja Andrei-Iosif dey44and Data 24 septembrie 2019 17:01:14
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.12 kb
#include <fstream>
#include <queue>

#define input "barbar.in"
#define output "barbar.out"
#define NMAX 1005

using namespace std;

ifstream in(input);
ofstream out(output);

struct point
{
    int x, y;
};
point paf_start, exit_stop;
queue < point > coada;

int dx[] = {0, 0, -1, 1};
int dy[] = {-1, 1, 0, 0};

int dragon_dist[NMAX][NMAX], dragon_bin[NMAX][NMAX], N, M;

bool OK(int x, int y)
{
    if(x < 1 || x > N || y < 1 || y > M)
        return false;
    return true;
}

void Read_Data()
{
    in >> N >> M;
    char c;
    for(int i = 1; i <= N; i++)
        for(int j = 1; j <= M; j++)
        {
            in >> c;
            if(c == 'I') paf_start = {i, j};
            else if(c == 'O') exit_stop = {i, j};
            else if(c == 'D')
            {
                dragon_dist[i][j] = 1;
                coada.push({i, j});
            }
            else if(c == '*')
                dragon_dist[i][j] = dragon_bin[i][j] = -1;
        }
}

void Lee_Dragons()
{
    while(!coada.empty())
    {
        point p = coada.front();
        coada.pop();
        for(int d = 0; d < 4; d++)
        {
            int x_new = dx[d] + p.x;
            int y_new = dy[d] + p.y;
            if(OK(x_new, y_new) && dragon_dist[x_new][y_new] == 0)
            {
                dragon_dist[x_new][y_new] = dragon_dist[p.x][p.y] + 1;
                coada.push({x_new, y_new});
            }
        }
    }
}

void Print_Dragons_Map()
{
    for(int i = 1; i <= N; i++)
    {
        for(int j = 1; j <= M; j++)
            out << dragon_dist[i][j] << " ";
        out << "\n";
    }
}

void Print_Binary_Map()
{
    for(int i = 1; i <= N; i++)
    {
        for(int j = 1; j <= M; j++)
            out << dragon_bin[i][j] << " ";
        out << "\n";
    }
}

void Empty_Map()
{
    for(int i = 1; i <= N; i++)
        for(int j = 1; j <= M; j++)
            if(dragon_bin[i][j] != -1)
                dragon_bin[i][j] = 0;
}

bool Lee(int diss)
{
    Empty_Map();
    dragon_bin[paf_start.x][paf_start.y] = 1;
    coada.push(paf_start);
    while(!coada.empty())
    {
        point p = coada.front();
        coada.pop();
        for(int d = 0; d < 4; d++)
        {
            int x_new = p.x + dx[d];
            int y_new = p.y + dy[d];
            if(OK(x_new, y_new) && dragon_bin[x_new][y_new] == 0 && dragon_dist[x_new][y_new] >= diss)
            {
                dragon_bin[x_new][y_new] = dragon_bin[p.x][p.y] + 1;
                coada.push({x_new, y_new});
            }
        }
    }
    //Print_Binary_Map();
    //out << "\n";
    if(dragon_bin[exit_stop.x][exit_stop.y] > 0) return true;
    return false;
}

void Binary_Search()
{
    //Print_Dragons_Map();
    //out << "\n";
    int st = 1, dr = N + M, sol = -1;
    while(st <= dr)
    {
        int midd = (st + dr) / 2;
        if(Lee(midd))
            st = midd + 1, sol = midd;
        else
            dr = midd - 1;
    }
    if(sol == -1) out << -1;
    else out << sol - 1;
}

int main()
{
    Read_Data();
    Lee_Dragons();
    Binary_Search();
    return 0;
}