Cod sursa(job #2080157)

Utilizator SmitOanea Smit Andrei Smit Data 2 decembrie 2017 15:11:11
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.71 kb
#include <bits/stdc++.h>
#define INF 2000000000

using namespace std;

struct elem{
    int x,y;
};

int N,M,xi,yi,xf,yf,sol,LIMITA;
char a[1003][1003];
int b[1003][1003],distDr[1003][1003];
int dx[]={-1,+1, 0, 0};
int dy[]={ 0, 0,-1,+1};
bool primaApelare=true;
queue<elem>q;

void InitB()
{
    int i,j;
    for(i=1;i<=N;++i)
        for(j=1;j<=M;++j)
            b[i][j]=INF;
}


void Citire()
{
    int i,j;
    char c;
    elem w;
    ifstream fin("barbar.in");
    fin>>N>>M;
    InitB();
    for(i=1;i<=N;++i)
    {
        fin>>(a[i]+1);
        for(j=1;j<=M;++j)
        {
            c=a[i][j];
            if(c=='I')
            {
                xi=i;
                yi=j;
            }
            if(c=='O')
            {
                xf=i;
                yf=j;
            }
            if(c=='D')
            {
                w.x=i;
                w.y=j;
                q.push(w);
                b[i][j]=0;
            }
        }
    }
    fin.close();
}

inline bool InMat(int x,int y)
{
    return (x>=1 && x<=N && y>=1 && y<=M);
}

inline bool Obstacol(int i,int j)
{

    if(primaApelare)
        return false;
    return (a[i][j]=='D' || a[i][j]=='*' || (a[i][j]=='.' && distDr[i][j]<LIMITA));
}

void Lee()
{
    int k;
    elem w,w1;
    while(!q.empty())
    {
        w=q.front();
        q.pop();
        if(Obstacol(w.x,w.y))
            ;
        else
        {
            for(k=0;k<4;++k)
            {
                w1.x=w.x + dx[k];
                w1.y=w.y + dy[k];
                if(InMat(w1.x,w1.y) && !Obstacol(w1.x,w1.y)
                   && b[w1.x][w1.y]>b[w.x][w.y]+1)
                {
                    b[w1.x][w1.y] = b[w.x][w.y] + 1;
                    q.push(w1);
                }
            }
        }
    }
    primaApelare=false;
}

void CautBin()
{
    int mijl,st,dr;
    elem w;
    st=0;
    dr=N+M+1;
    while(st<=dr)
    {
        mijl=(st+dr)/2;
        LIMITA=mijl;
        w.x=xi;
        w.y=yi;
        q.push(w);
        InitB();
        b[w.x][w.y]=0;
        Lee();
        if(b[xf][yf]!=INF)//am putut ajunge
        {
            sol=mijl;//salvez solutia
            st=mijl+1;//incerc o limita mai mare
        }
        else//nu am putut
            dr=mijl-1;//incerc o limita mai mica
    }
}

void Afisare()
{
    ofstream fout("barbar.out");
    fout<<sol<<"\n";
    fout.close();
}

int main()
{
    int i,j;
    Citire();
    LIMITA=-1;

    Lee();//calculez distDr
    for(i=1;i<=N;++i)
        for(j=1;j<=M;++j)
            distDr[i][j]=b[i][j];

    //caut binar solutia
    sol=-1;
    CautBin();
    Afisare();
    return 0;
}