Cod sursa(job #3141783)

Utilizator Chris_BlackBlaga Cristian Chris_Black Data 16 iulie 2023 15:22:26
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.71 kb
#include <fstream>
#include <cstring>
#include <queue>

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

const int NMAX = 1e3;
int a[NMAX + 5][NMAX + 5], dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, 1, -1}, viz[NMAX + 5][NMAX + 5], n, m;
const int INF = 1e7;

struct point
{
    int x, y;
};
point start, finish;
queue <point> q;

void border_matrix()
{
    for(int i = 0; i <= n + 1; i++)
        a[i][m + 1] = a[i][0] = -5;

    for(int i = 0; i <= m + 1; i++)
        a[0][i] = a[n + 1][i] = -5;
}

void lee()
{
    while(!q.empty())
    {
        point curr = q.front();
        int x = curr.x, y = curr.y;
        q.pop();

        for(int i = 0; i < 4; i++)
        {
            int new_x = x + dx[i], new_y = y + dy[i];

            if(a[new_x][new_y] >= 0)
            {
                if(a[x][y] == -1)
                {
                    a[new_x][new_y] = 1;

                    point new_point;
                    new_point.x = new_x;
                    new_point.y = new_y;
                    q.push(new_point);
                }
                else if(a[new_x][new_y] > a[x][y] + 1)
                {
                    a[new_x][new_y] = a[x][y] + 1;
                    point new_point;
                    new_point.x = new_x;
                    new_point.y = new_y;
                    q.push(new_point);
                }
            }
        }
    }
}

void possible(int x, int y, int least)
{
    viz[x][y] = 1;

    for(int i = 0; i < 4; i++)
    {
        int new_x = x + dx[i], new_y = y + dy[i];

        if(((a[new_x][new_y] >= least and a[new_x][new_y] >= 0) or a[new_x][new_y] == -3) and viz[new_x][new_y] == 0)
            possible(new_x, new_y, least);
    }
}

int binary_search_minimum()
{
    int left = 0, right = n * m + 1, mid, good = -1;

    while(left <= right)
    {
        mid = (left + right) / 2;

        if(((a[start.x][start.y] >= mid and a[start.x][start.y] >= 0) or a[start.x][start.y] == -3) and viz[start.x][start.y] == 0)
            possible(start.x, start.y, mid);

        if(viz[finish.x][finish.y] == 1)
        {
            left = mid + 1;
            good = mid;
        }
        else right = mid - 1;

        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++)
                if(viz[i][j] >= 0)
                    viz[i][j] = 0;
    }

    return good;
}

int main()
{
    fin >> n >> m;

    for(int i = 1; i <= n; i++)
    {
        string s;
        fin >> s;

        for(int j = 0; j < s.size(); j++)
            if(s[j] == 'D')
            {
                a[i][j + 1] = -1;
                viz[i][j + 1] = -1;
            }
            else if(s[j] == '*')
            {
                a[i][j + 1] = -2;
                viz[i][j + 1] = -1;
            }
            else if(s[j] == 'O')
            {
                a[i][j + 1] = -3;
                finish.x = i;
                finish.y = j + 1;
            }
            else if(s[j] == 'I')
            {
                a[i][j + 1] = -4;
                start.x = i;
                start.y = j + 1;
            }
    }

    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            if(a[i][j] == 0 or a[i][j] == -3 or a[i][j] == -4)
                a[i][j] = INF;

    border_matrix();

    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            if(a[i][j] == -1)
            {
                point dragon;
                dragon.x = i;
                dragon.y = j;
                q.push(dragon);
            }

    lee();
    fout << binary_search_minimum();

    fin.close();
    fout.close();
    return 0;
}