Cod sursa(job #2665331)

Utilizator Silviu.Stancioiu@gmail.comSilviu Stancioiu [email protected] Data 30 octombrie 2020 16:00:22
Problema Barbar Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.72 kb
#include <fstream>
#include <iostream>
#include <queue>

using namespace std;

ifstream fin("barbar.in");
ofstream fout("barbar.out");
int r, c;
int** dragons_distances;
int** viz;
pair<int, int> beg_pos;
pair<int, int> end_pos;
queue<pair<int, int>> bfs_queue;
int dy[] = { -1, 0, 1, 0 };
int dx[] = { 0, -1, 0, 1 };

bool valid_pos(const pair<int, int> pos)
{
    if (pos.first >= 0 && pos.first < r &&
        pos.second >= 0 && pos.second < c)
        return dragons_distances[pos.first][pos.second] != -2;
    
    return false;
}

bool verify(const int threshold)
{
    if (dragons_distances[beg_pos.first][beg_pos.second] < threshold)
        return false;

    viz[beg_pos.first][beg_pos.second] = threshold;
    bfs_queue.push(beg_pos);

    while (!bfs_queue.empty())
    {
        const auto crt_node = bfs_queue.front();
        bfs_queue.pop();

        for (auto i = 0; i < 4; i++)
        {
            auto new_pos = make_pair(crt_node.first + dx[i], crt_node.second + dy[i]);
            if (valid_pos(new_pos))
            {
                if (viz[new_pos.first][new_pos.second] != threshold && dragons_distances[new_pos.first][new_pos.second] >= threshold)
                {
                    viz[new_pos.first][new_pos.second] = threshold;
                    bfs_queue.push(new_pos);
                }
            }
        }
    }

    return viz[end_pos.first][end_pos.second] == threshold;
}

int main()
{
    fin >> r >> c;

    dragons_distances = new int*[r];
    viz = new int* [r];
    for (auto i = 0; i < r; i++)
    {
        dragons_distances[i] = new int[c];
        viz[i] = new int[c];
        memset(dragons_distances[i], 0, sizeof(int) * c);
        memset(viz[i], 0, sizeof(int) * c);
    }

    for (auto i = 0; i < r; i++)
    {
        for (auto j = 0; j < c; j++)
        {
            char chr;
            fin >> chr;
            dragons_distances[i][j] = -1;
            switch (chr)
            {
            case '.':
                dragons_distances[i][j] = -1;
                break;
            case '*':
                dragons_distances[i][j] = -2;
                break;
            case 'D':
                dragons_distances[i][j] = 0;
                bfs_queue.push(make_pair(i, j));
                break;
            case 'I':
                dragons_distances[i][j] = -1;
                beg_pos = make_pair(i, j);
                break;
            case 'O':
                dragons_distances[i][j] = -1;
                end_pos = make_pair(i, j);
                break;
            default: ;
            }
        }
    }

    auto max_dist = 0;

    while (!bfs_queue.empty())
    {
        const auto& node = bfs_queue.front();
        bfs_queue.pop();

        const auto dist = dragons_distances[node.first][node.second];
        max_dist = max(max_dist, dist);

        for (auto i = 0; i < 4; i++)
        {
            auto new_pos = make_pair(node.first + dx[i], node.second + dy[i]);
            if (valid_pos(new_pos))
            {
                if (dragons_distances[new_pos.first][new_pos.second] == -1)
                {
                    dragons_distances[new_pos.first][new_pos.second] = dist + 1;
                    bfs_queue.push(new_pos);
                }
            }
        }
    }

    auto index = 0;
    for (auto i = 1 << 25; i >= 1; i >>= 1)
        if (index + i <= max_dist)
            if (verify(index + i))
                index += i;

    fout << (index == 0 ? -1 : index);

    for (auto i = 0; i < r; i++)
    {
        delete[] dragons_distances[i];
        delete[] viz[i];
    }

    delete[] dragons_distances;
    delete[] viz;
   
    return 0;
}