Cod sursa(job #1113501)

Utilizator gbi250Gabriela Moldovan gbi250 Data 20 februarie 2014 17:41:53
Problema Barbar Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.68 kb
#include <cstdio>
#include <queue>
#define SIZE 1001
using namespace std;

int r, c, xi, yi, xf, yf, dist_min[SIZE][SIZE];
bool M[SIZE][SIZE], visited[SIZE][SIZE];
queue < pair< int, int > > q;

inline void read();
inline void solve();
inline void write();

int main()
{
    read();
    solve();
    write();
    return 0;
}

inline void read()
{
    freopen("barbar.in", "r", stdin);
    scanf("%d%d", &r, &c);
    for(int i = 1; i <= r; ++i)
    {
        for(int j = 1; j <= c; ++j)
        {
            scanf("%c", &c);
            if( c == '.' )
                M[ i ][ j ] = 1;
            else if( c == 'I' )
            {
                M[ i ][ j ] = 1;
                xi = i;
                yi = j;
            }
            else if( c == 'O')
            {
                M[ i ][ j ] = 1;
                xf = i;
                yf = j;
            }
            else if( c == 'D' )
                q.push( make_pair(i , j) );
        }
    }
}

inline bool ok(int lin, int col)
{
    return lin >= 1 && lin <= r && col >= 1 && col <= c;
}

bool check_dist(int distance)
{
    memset( visited, 0, sizeof(visited));

    q.push( make_pair( xi, yi ));

    const int dl[ ] = { -1, 0, 1, 0}, dc[ ] = { 0, 1, 0, -1 };

    while( ! q.empty() )
    {
        int lin = q.front().first;
        int col = q.front().second;
        q.pop();
        for(int i = 0; i < 4; ++i)
        {
            int new_lin = lin + dl[i];
            int new_col = col + dc[i];
            if( ok(new_lin, new_col) && !visited[ new_lin ][ new_col ] && dist_min[ new_lin ][ new_col ] >= distance )
            {
                visited[ new_lin ][ new_col ] = 1;
                if( new_lin == xf && new_col == yf )
                    return 1;
                q.push( make_pair ( new_lin, new_col ) );
            }
        }
    }
    return 0;
}

inline void solve()
{
    const int dl[ ] = { -1, 0, 1, 0}, dc[ ] = { 0, 1, 0, -1 };
    while( ! q.empty() )
    {
        int lin = q.front().first;
        int col = q.front().second;
        q.pop();
        for(int i = 0; i < 4; ++i)
        {
            int new_lin = lin + dl[i];
            int new_col = col + dc[i];
            if( ok(new_lin, new_col) && !visited[ new_lin ][ new_col ] && M[ new_lin ][ new_col ] )
            {
                visited[ new_lin ][ new_col ] = 1;
                dist_min[ new_lin ][ new_col ] = dist_min[ lin ][ col ] + 1;
                q.push( make_pair ( new_lin, new_col ) );
            }
        }
    }
}

inline void write()
{
    freopen("barbar.out", "w", stdout);
    for(int i = dist_min[ xi ][ yi ]; i >= 1; --i)
        if( check_dist( i ) )
        {
            printf("%d\n", i);
            return ;
        }
    printf("-1\n");
}