Cod sursa(job #1885627)

Utilizator rangalIstrate Sebastian rangal Data 20 februarie 2017 10:14:26
Problema Barbar Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.38 kb
#include <fstream>
#define in "barbar.in"
#define out "barbar.out"
#define NM 1003

using namespace std;

ifstream fin(in);
ofstream fout(out);

int n,m;
char c[NM][NM];
bool v[NM][NM];

struct Pc{
    int i,j;
}coada[NM*NM],A,B;

int diri[]={-1,0,1,0};
int dirj[]={0,1,0,-1};

inline void memsett()
{
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=m; ++j)
            v[i][j] = 0;
}

inline bool posib(int I,int J,int r)
{
    if(v[I][J] == 1) return 0;
    if(c[I][J] == '*') return 0;

    for(int i=1; i<=r && I+i<=n; ++i)
        if(c[I+i][J] == 'D') return 0;
    for(int i=1; i<=r && I-i>0; ++i)
        if(c[I-i][J] == 'D') return 0;
    for(int j=1; j<=r && J+j<=m; ++j)
        if(c[I][J+j] == 'D') return 0;
    for(int j=1; j<=r && J-j>0; ++j)
        if(c[I][J-j] == 'D') return 0;
    return 1;
}

inline bool LeeEok(int r)
{
    memsett();
    int st,dr;
    st = dr = 1;

    v[A.i][A.j] = 1;
    coada[st].i = A.i;
    coada[st].j = A.j;

    int I,J;

    while(st<=dr)
    {
        for(int k=0; k<4; ++k)
        {
            I = coada[st].i + diri[k];
            J = coada[st].j + dirj[k];
            if(posib(I,J,r))
            {
                v[I][J] = 1;
                ++dr;
                coada[dr].i = I;
                coada[dr].j  =J;
            }
        }
        ++st;
    }
    if(v[B.i][B.j] == 1) return true;
    return false;
}

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

int LgMin()
{
    if(!LeeEok(0)) return -1;

    int rez = 0;

    int st,dr,mij;
    st = 1; dr = min(n,m);

    while(st<=dr)
    {
        mij = (st+dr)/2;
        if(LeeEok(mij))
        {
            rez = max(rez,mij);
            st = mij +1;
        }
        else
            dr = mij - 1;
    }

    return rez+1;
}

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

    int i,j;
    for(i=1; i<=n; ++i)
    {
        for(j=1; j<=m; ++j)
        {
            fin>>c[i][j];
            if(c[i][j] == 'I')
                A.i = i, A.j = j;
            if(c[i][j] == 'O')
                B.i = i, B.j = j;
        }
        fin.get();
    }

    //fout<<A.i<<" "<<A.j<<"\n"<<B.i<<" "<<B.j;

    Bordare();

    fout<<LgMin();

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