Cod sursa(job #2480743)

Utilizator NopeCarp Rafael Nope Data 26 octombrie 2019 09:25:04
Problema Barbar Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.96 kb
#include <bits/stdc++.h>
using namespace std;

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

pair<int , int> v[1000005];
char a[1005][1005];
int b[1005][1005] , n , m , k;
int xi, yi , xo , yo;
bitset<1005> c[1005];
/// b[i][j] - distanta minima de la (i , j) la un dragon

void Citire()
{
    fin >> n >> m;
    for (int i = 1; i <= n ; i++)
        fin >> (a[i] + 1);
}

void Bordare()
{
    int i;
    for (i = 0 ; i <= n + 1 ; i++)
        a[i][0] = a[i][m + 1] = '*';
    for (i = 0 ; i <= m + 1 ; i++)
        a[0][i] = a[n + 1][i] = '*';
}

void Initializare()
{
    int i , j;
    for (i = 1 ; i <= n ; i++)
        for (j = 1 ; j <= m ; j++)
        {
            if (a[i][j] == 'I')
            {
                xi = i;
                yi = i;
            }
            if (a[i][j] == 'O')
            {
                xo = i;
                yo = j;
            }
            if (a[i][j] == 'D')
            {
                b[i][j] = 0;
                k++;
                v[k] = {i , j};
            }
            else b[i][j] = 2000000;
        }
}

void Distante()
{
    int i , j , x , y;
    while(k > 0)
    {
        i = v[k].first;
        j = v[k].second;
        k--;
        /// nord
        x = i - 1;
        y = j;
        if (a[x][y] != '*' && b[x][y] > 1 + b[i][j])
        {
            b[x][y] = 1 + b[i][j];
            k++;
            v[k] = {x , y};
        }
        /// sud
        x= i + 1;
        y = j;
        if (a[x][y] != '*' && b[x][y] > 1 + b[i][j])
        {
            b[x][y] = 1 + b[i][j];
            k++;
            v[k] = {x , y};
        }
        /// est
        x = i;
        y = j + 1;
        if (a[x][y] != '*' && b[x][y] > 1 + b[i][j])
        {
            b[x][y] = 1 + b[i][j];
            k++;
            v[k] = {x , y};
        }
        /// vest
        x = i;
        y = j - 1;
        if (a[x][y] != '*' && b[x][y] > 1 + b[i][j])
        {
            b[x][y] = 1 + b[i][j];
            k++;
            v[k] = {x , y};
        }
    }
}
/// verific daca pot ajunge de la I la O mergand doar pe valori
/// >= cu val
void Fill(short i , short j , int val)
{
    if (a[i][j] != '*' && b[i][j] >= val && c[i][j] == 0)
    {
        c[i][j] = 1;
        Fill(i - 1 , j , val);
        Fill(i + 1 , j , val);
        Fill(i , j - 1 , val);
        Fill(i , j + 1 , val);
    }
}

void CB()
{
    int st , dr , mij , Val , i;
    st = 1;
    dr = b[xi][yi];
    Val = -1;
    while(st <= dr)
    {
        mij = (st + dr) / 2;
        for (i = 1 ; i <= n ; i++)
            c[i].reset();
        Fill(xi , yi , mij);
        if (c[xo][yo] == 1)
        {
            Val = mij;
            st = mij + 1;
        }
        else dr = mij - 1;
    }
    fout << Val << "\n";
    fout.close();
}


int main()
{
    Citire();
    Bordare();
    Initializare();
    Distante();
    CB();
    return 0;
}