Cod sursa(job #2480747)

Utilizator ginaiulianaGina Iuliana ginaiuliana Data 26 octombrie 2019 09:25:21
Problema Barbar Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.06 kb
#include <bits/stdc++.h>
using namespace std;

pair<int, int> v[1000005];
ifstream fin ("barbar.in");
ofstream fout ("barbar.out");

char a[1005][1005];
int b[1005][1005], n, m, k;
bitset <1003> c[1003];
int xi, yi, xo, yo;
///b[i][j]-distanta minima posibila de la poz 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 Initial()
{
    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] > b[i][j] + 1)
        {
            b[x][y] = b[i][j] + 1;
            k++;
            v[k] = {x, y};
        }
        ///sud
        x = i + 1;
        y = j;
        if(a[x][y] != '*' && b[x][y] > b[i][j] + 1)
        {
            b[x][y] = b[i][j] + 1;
            k++;
            v[k] = {x, y};
        }
        ///est
        x = i;
        y = j + 1;
        if(a[x][y] != '*' && b[x][y] > b[i][j] + 1)
        {
            b[x][y] = b[i][j] + 1;
            k++;
            v[k] = {x, y};
        }
        ///vest
        x = i;
        y = j - 1;
        if(a[x][y] != '*' && b[x][y] > b[i][j] + 1)
        {
            b[x][y] = b[i][j] + 1;
            k++;
            v[k] = {x, y};
        }
    }
}

///verific daca pot ajunge de la i la o
///mergand pe val >=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 CautBin()
{
    int i, st, dr, mij, val;
    st = 1;
    dr = b[xi][yi];
    while(st <= dr)
    {
        mij = (st + dr)/ 2;
        for(i = 1; i <= n; i++)
            c[i].reset();
        Fill(xi, yi, val);
        if(c[xo][yo] == 1)
        {
            val = mij;
            st = mij + 1;
        }
        else dr = mij-1;
    }
}
void Rez()
{
    int i, val;
    for(val = b[xi][yi]; val >= 1; val-- )
    {
        for(i = 1; i <= n; i++)
            c[i].reset();
        Fill(xi, yi, val);
        if(c[xo][yo] == 1)
        {
            fout << val << "\n";
            fout.close();
            return;
        }
    }
    fout << "-1\n";
    fout.close();
}

int main()
{
    Citire();
    Bordare();
    Initial();
    Distante();
    CautBin();
    return 0;
}