Cod sursa(job #1887371)

Utilizator Storm_FireFox1Matei Gardus Storm_FireFox1 Data 21 februarie 2017 15:56:18
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.17 kb
#include <fstream>
#define in "barbar.in"
#define out "barbar.out"
#define NM 1003
#define oo 2000000000
 
using namespace std;
 
ifstream fin(in);
ofstream fout(out);
 
int n,m;
char c[NM][NM];
bool v[NM][NM];
int dmin[NM][NM]; // pentru fiecare casuta vedem drumul minim pana la primul dragon
 
struct Pc{
    int i,j;
}coada[NM*NM],A,B;
 
int diri[]={-1,0,1,0};
int dirj[]={0,1,0,-1};
 
void LeeD()
{
    int st,dr;
    dr = 0;
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=m; ++j)
            if(c[i][j] == 'D')
            {
                ++dr;
                coada[dr].i = i;
                coada[dr].j = j;
                v[i][j] = 1;
            }
    st = 1;
    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(!dmin[I][J] && c[I][J] != '*' && c[I][J] != 'D')
            {
                dmin[I][J] = dmin[coada[st].i][coada[st].j] + 1;
                ++dr;
                coada[dr].i = I;
                coada[dr].j  =J;
            }
        }
        ++st;
    }
}
 
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] = '*';
}
 
 
inline bool posib(int I,int J,int r)
{
    if(v[I][J] == 1) return 0;
    if(c[I][J] == '*' || c[I][J] == 'D') return 0;
    if(dmin[I][J] < r) return 0;
    return 1;
}
 
inline void memsett()
{
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=m; ++j)
            v[i][j] = 0;
}
 
inline bool LeeEok(int r)
{
    memsett();
    int st,dr;
    st = dr = 1;
 
    if(!posib(A.i,A.j,r)) return 0;
 
    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;
}
 
 
int LgMin()
{
    if(!LeeEok(0)) return -1;
 
    int rez = 0;
 
    int st,dr,mij;
    st = 1; dr = max(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;
}
 
void afisare()
{
    for(int i=1; i<=n; ++i)
    {
        for(int j=1; j<=m; ++j)
            fout<<dmin[i][j]<<" ";
        fout<<"\n";
    }
}
 
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();
    }
 
    Bordare();
    LeeD();
 
    //afisare();
 
    fout<<LgMin();
 
    fin.close(); fout.close();
    return 0;
}