Cod sursa(job #1887539)

Utilizator BourucLiviuBouruc Petru Liviu BourucLiviu Data 21 februarie 2017 17:36:42
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.55 kb
#include <fstream>
#include <cstring>

using namespace std;

struct poz
{
    int x, y;
} coada[1005*1005];
const int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int prim, ultim;

int n, m, xi, yi, xf, yf, b[1005][1005];
bool a[1005][1005];

void MEMSET()
{
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j) a[i][j] = 0;
}
void bordare()
{
    for(int i = 0; i <= n + 1; ++i) a[i][0] = b[i][0] = a[i][m+1] = b[i][m+1] = -1;
    for(int i = 0; i <= m + 1; ++i) a[0][i] = b[0][i] = a[n+1][i] = b[m+1][i] = -1;
}

bool Lee(int r)
{
    MEMSET();
    bordare();
    a[xi][yi] = 1;
    prim = ultim = 1;
    coada[prim].x = xi; coada[prim].y = yi;
    while(prim <= ultim)
    {
        for(int d = 0; d < 4; ++d)
        {
            int l = coada[prim].x + dx[d], c = coada[prim].y + dy[d];
            if(a[l][c] == 0 && b[l][c] >= r)
            {
                a[l][c] = 1;
                ultim++;
                coada[ultim].x = l; coada[ultim].y = c;
            }
        }
        prim++;
    }
    if(a[xf][yf]) return 1;
    return 0;
}

void LeeD()
{
    prim = 1;
    while(prim <= ultim)
    {
        int X = coada[prim].x, Y = coada[prim].y;
        for(int d = 0; d < 4; d++)
        {
            int l = X + dx[d], c = Y + dy[d];
            if(b[l][c] == 0)
            {
                b[l][c] = b[X][Y] + 1;
                ultim++;
                coada[ultim].x = l; coada[ultim].y = c;
            }
        }
        prim++;
    }
}

int LgMin()
{
    int st = 1, dr = min(n, m), mij, rez = 0;
    while(st <= dr)
    {
        mij = (st + dr) / 2;
        if(Lee(mij))
        {
            rez = mij;
            st = mij + 1;
        }
        else dr = mij - 1;
    }
    return rez - 1;
}

int main()
{
    char c;
    ifstream fin ("barbar.in");
    fin >> n >> m;
    fin.get();
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= m; ++j)
        {
            fin >> c;
            if(c == 'I') xi = i, yi = j;
            else if(c == 'O') xf = i, yf = j;
            else if(c == 'D')
            {
                b[i][j] = 1;
                ultim++;
                coada[ultim].x = i;
                coada[ultim].y = j;
            }
            else if(c == '*') b[i][j] = -1;
        }
        fin.get();
    }
    fin.close();

    bordare();
    LeeD();

    ofstream fout ("barbar.out");
    if(!Lee(1))
    {
        fout << "-1";
        return 0;
    }
    fout << LgMin();
    fout.close();
    return 0;
}