Cod sursa(job #3139032)

Utilizator andreipirjol5Andrei Pirjol andreipirjol5 Data 24 iunie 2023 13:43:19
Problema Barbar Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.72 kb
#include <fstream>
#include <cstring>

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;
void fill(int x, int y)
{
    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;
                fill(new_x, new_y);
            }
            else if(a[new_x][new_y] > a[x][y] + 1)
            {
                a[new_x][new_y] = a[x][y] + 1;
                fill(new_x, new_y);
            }
        }
    }
}

struct point
{
    int x, y;
};
point start, finish;

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 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 = 1, right = n * m + 1, mid, good = -1;

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

        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)
                a[i][j] = INF;

    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            if(a[i][j] == -1)
                fill(i, j);

    fout << binary_search_minimum();

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