Cod sursa(job #2299626)

Utilizator Dragne.Andrei11Dragne Andrei Dragne.Andrei11 Data 9 decembrie 2018 20:11:26
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.63 kb
#include <bits/stdc++.h>

using namespace std;

const short nmax=1001;

char ma[nmax][nmax];
bool visited[nmax][nmax];
deque <pair <int, pair <int, int> > > coada;
deque <pair <int, int> > le;
int dist[nmax][nmax];

int n, m;
int i_out, j_out;
int i_in, j_in;

void initial(int n, int m)
{
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            dist[i][j]=-1;
}

void cl()
{
    le.clear();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            visited[i][j]=false;
}

bool lee(int d)
{
    le.push_back(make_pair(i_in, j_in));
    while(le.size()>0)
    {
        pair <int, int> curent;
        curent=le.front();
        int a=curent.first;
        int b=curent.second;
        if(visited[a][b+1]==false&&dist[a][b+1]>=d&&b+1<=m)
        {
            visited[a][b+1]=true;
            le.push_back(make_pair(a, b+1));
            if(a==i_out&&b+1==j_out)
                return true;
        }
        if(visited[a][b-1]==false&&dist[a][b-1]>=d&&b-1>=1)
        {
            visited[a][b-1]=true;
            le.push_back(make_pair(a, b-1));
            if(a==i_out&&b-1==j_out)
                return true;
        }
        if(visited[a+1][b]==false&&dist[a+1][b]>=d&&a+1<=n)
        {
            visited[a+1][b]=true;
            le.push_back(make_pair(a+1, b));
            if(a+1==i_out&&b==j_out)
                return true;
        }
        if(visited[a-1][b]==false&&dist[a-1][b]>=d&&a-1>=1)
        {
            visited[a-1][b]=true;
            le.push_back(make_pair(a-1, b));
            if(a-1==i_out&&b==j_out)
                return true;
        }
        le.pop_front();
    }
    return false;
}

int rasp(int beg, int fin)
{
    int last=-1;
    int med=(beg+fin)/2;
    while(beg<=fin)
    {
        cl();
        bool q=lee(med);
        if(q==true)
        {
            last=med;
            beg=med+1;
        }
        else
            fin=med-1;
        cl();
        med=(beg+fin)/2;
    }
    return last;
}

int main()
{
    freopen("barbar.in", "r", stdin);
    freopen("barbar.out", "w", stdout);

    scanf("%d %d\n", &n, &m);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            scanf("%c", &ma[i][j]);
            switch(ma[i][j])
            {
                case 'I':i_in=i;j_in=j;break;
                case 'O':i_out=i;j_out=j;break;
                case 'D':dist[i][j]=0;visited[i][j]=true;coada.push_back(make_pair(0, make_pair(i, j)));
                case '*':dist[i][j]=-2;visited[i][j]=true;break;
            }
        }
        char c;
        scanf("%c", &c);
    }
    int maxim=-1;
    while(coada.size()>0)
    {
        pair <int, pair <int, int> > curent;
        curent=coada.front();
        if(visited[curent.second.first][curent.second.second+1]==false&&curent.second.second+1<=m)
        {
            maxim=max(maxim, curent.first+1);
            dist[curent.second.first][curent.second.second+1]=curent.first+1;
            visited[curent.second.first][curent.second.second+1]=true;
            coada.push_back(make_pair(curent.first+1, make_pair(curent.second.first, curent.second.second+1)));
        }
        if(visited[curent.second.first][curent.second.second-1]==false&&curent.second.second-1>=1)
        {
            maxim=max(maxim, curent.first+1);
            dist[curent.second.first][curent.second.second-1]=curent.first+1;
            visited[curent.second.first][curent.second.second-1]=true;
            coada.push_back(make_pair(curent.first+1, make_pair(curent.second.first, curent.second.second-1)));
        }
        if(visited[curent.second.first+1][curent.second.second]==false&&curent.second.first+1<=n)
        {
            maxim=max(maxim, curent.first+1);
            dist[curent.second.first+1][curent.second.second]=curent.first+1;
            visited[curent.second.first+1][curent.second.second]=true;
            coada.push_back(make_pair(curent.first+1, make_pair(curent.second.first+1, curent.second.second)));
        }
        if(visited[curent.second.first-1][curent.second.second]==false&&curent.second.first-1>=1)
        {
            maxim=max(maxim, curent.first+1);
            dist[curent.second.first-1][curent.second.second]=curent.first+1;
            visited[curent.second.first-1][curent.second.second]=true;
            coada.push_back(make_pair(curent.first+1, make_pair(curent.second.first-1, curent.second.second)));
        }
        coada.pop_front();
    }
    if(dist[i_out][j_out]==-1)
    {
        printf("-1\n");
        return 0;
    }
    printf("%d\n", rasp(0, maxim));

    return 0;
}