Cod sursa(job #1886737)

Utilizator rangalIstrate Sebastian rangal Data 21 februarie 2017 09:23:59
Problema Barbar Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.13 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 Calc()
{
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=m; ++j)
        {
            int Min = oo;
            for(int i2 = i; i2>0 && i-i2 <= Min; --i2)
                if(c[i2][j] == 'D')
                    Min = min(Min,i-i2);

            for(int i2 = i; i2<=n && i2-i <= Min; ++i2)
                if(c[i2][j] == 'D')
                    Min = min(Min,i2-i);

            for(int j2 = j; j2>0 && j-j2 <=Min; --j2)
                if(c[i][j2] == 'D')
                    Min = min(Min,j-j2);
            for(int j2 = j; j2<=m && j2-j <=Min; ++j2)
                if(c[i][j2] == 'D')
                    Min = min(Min,j2-j);

            dmin[i][j] = Min;
        }
}

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;

    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();
    }

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

    Bordare();
    Calc();

    //afisare();

    fout<<LgMin();*/
    fout<<"-1\n";

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