Cod sursa(job #1198127)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 14 iunie 2014 17:36:34
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.58 kb
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>


#define Nmax 1005
#define INF 0x3f3f3f3f

using namespace std;

queue<pair<int,int> > Q;


char a[Nmax][Nmax];
char used[Nmax][Nmax];
int dist[Nmax][Nmax];
int DP[Nmax][Nmax];
int Sx,Sy,Ex,Ey;
int N,M;

const int dx[5]={0, 0,-1,0,1},
          dy[5]={0,-1, 0,1,0};

void read()
{
    scanf("%d%d",&N,&M);
    for(int i = 1; i <= N; ++i){
        scanf("%s",a[i]+1);
        for(int j = 1; j <= M; ++j)
        {
            if(a[i][j] == 'I'){
                Sx = i;
                Sy = j;
                a[i][j] = '.'; /// permitem trecerea
            }
            if(a[i][j] == 'O'){
                Ex = i;
                Ey = j;
                a[i][j] = '.'; /// permitem trecerea
            }
            if(a[i][j] == 'D')
            {
                Q.push(make_pair(i,j));
                dist[i][j] = 1;
            }
        }
        a[i][0] = '#';
    }
}

void sari(int x,int y,int k)
{
    if(dist[x][y]) return;
    dist[x][y] = k;
    Q.push(make_pair(x,y));
}

void precalc()
{
    int x,y,K,_x,_y;
    while(!Q.empty())
    {
        x = Q.front().first;
        y = Q.front().second;
        K = dist[x][y];
        Q.pop();
        for(int i = 1; i <= 4; ++i)
        {
            _x = x + dx[i];
            _y = y + dy[i];
            if(a[_x][_y] != '.') continue;
            sari(_x,_y,K+1);
        }
    }
    /**for(int i = 1; i <= N; ++i,printf("\n\n"))
        for(int j = 1; j <= M; ++j)
            printf("%3d",dist[i][j]);
    **/
}

int lee(int LIM)
{
    memset(DP,0,sizeof(DP));
    Q.push(make_pair(Sx,Sy));
    DP[Sx][Sy] = 1;
    int x,y,_x,_y;
    while(!Q.empty())
    {
        x = Q.front().first;
        y = Q.front().second;
        Q.pop();
        for(int i = 1; i <= 4; ++i)
        {
            _x = x + dx[i];
            _y = y + dy[i];
            if(a[_x][_y] != '.') continue;
            if(dist[_x][_y] < LIM) continue;
            if(DP[_x][_y]) continue;
            DP[_x][_y] = 1;
            Q.push(make_pair(_x,_y));
        }
    }
    return DP[Ex][Ey];
}

void solve()
{
    int li = 0,lf = dist[Sx][Sy],m;
    while(li <= lf)
    {
        m = li + ((lf-li)>>1);
        if(lee(m))
            li = m + 1;
        else
            lf = m - 1;
    }
    if(lf == -1) ++ lf;
    printf("%d\n",lf - 1);
}

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

    read();
    precalc();
    solve();

    return 0;
}