Cod sursa(job #2892451)

Utilizator andrei_marciucMarciuc Andrei andrei_marciuc Data 22 aprilie 2022 11:06:41
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.57 kb
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

#define MAXN 1002
#define MAX_DIR 4
static int dl[] = { 0, 1, 0, -1 };
static int dc[] = { 1, 0, -1, 0 };

struct Point{
    int l, c;
};

bool vizitat[ MAXN ][ MAXN ];
int dis[ MAXN ][ MAXN ];
char a[ MAXN ][ MAXN ];
queue<Point> q;
Point st;
int n, m;

bool valid( const Point& P ) {
    if( P.l >= 0 && P.l < n && P.c >= 0 && P.c < m )
        return true;
    return false;
}

void Lee() {
    Point point, curent; 
    while( !q.empty() ) {
        point = q.front();
        q.pop();

        for( int dir = 0; dir < MAX_DIR; dir++ ) {
            curent = { point.l + dl[ dir ], point.c + dc[ dir ] };
            if( valid( curent ) && dis[ curent.l ][ curent.c ] == 0 && a[ curent.l ][ curent.c ] != '*' && a[ curent.l ][ curent.c ] != 'I' ) {
                dis[ curent.l ][ curent.c ] = dis[ point.l ][ point.c ] + 1;
                q.push( curent );
            }
        }
    }
}

void reset() {
    while( !q.empty() )
        q.pop();

    memset( vizitat, 0, sizeof( vizitat ) );
}

bool ExistaDrum( int val ) {
    q.push( st );
    Point point, curent; 
    while( !q.empty() ) {
        point = q.front();
        q.pop();

        for( int dir = 0; dir < MAX_DIR; dir++ ) {
            curent = { point.l + dl[ dir ], point.c + dc[ dir ] };
            if( valid( curent ) && a[ curent.l ][ curent.c ] != '*' && vizitat[ curent.l ][ curent.c ] == 0 && dis[ curent.l ][ curent.c ] >= val ) {
                vizitat[ curent.l ][ curent.c ] = 1;
                if( a[ curent.l ][ curent.c ] == 'O' ) {
                    reset();
                    return true;
                } else q.push( curent );
            }
        }
    }
    reset();
    return false;
}

int raspuns() {
    int left = 0, sol = 0;
    int right = 2 * MAXN + 10, med;

    while( left <= right ) {
        med = ( left + right ) >> 1;
        if( ExistaDrum( med ) ) {
            left = med + 1;
            sol = med;
        } else right = med - 1;
    }

    return sol - 1;
}

int main()
{
    FILE *fin = fopen( "barbar.in", "r" );
    fscanf( fin, "%d %d\n", &n, &m );
    for( int l = 0; l < n; l++ )
        fscanf( fin, "%s\n", a[ l ] );
    fclose( fin );

    for( int l = 0; l < n; l++ )
        for( int c = 0; c < m; c++ )
            if( a[ l ][ c ] == 'D' ) {
                dis[ l ][ c ] = 1;
                q.push( { l, c } );
            } else if( a[ l ][ c ] == 'I' )
                st = { l, c };

    Lee();

    FILE *fout = fopen( "barbar.out", "w" );
    fprintf( fout, "%d\n", raspuns() );
    fclose( fout );
    return 0;
}