Cod sursa(job #2792778)

Utilizator LucaMihaiLM10Luca Ilie LucaMihaiLM10 Data 2 noiembrie 2021 12:05:32
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.44 kb
#include <stdio.h>
#include <queue>

#define MAX_N 1000
#define DIR 4

using namespace std;

struct punct {
    int l, c;
    struct punct operator + (const punct &p) {
        return { l + p.l, c + p.c };
    }
};

punct dir[DIR] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } };
int mat[MAX_N + 2][MAX_N + 2], dist[MAX_N + 2][MAX_N + 2], viz[MAX_N + 2][MAX_N + 2];
queue <punct> q;

void dfs( punct crt ) {
    int d;
    punct next;

    viz[crt.l][crt.c] = 1;

    for ( d = 0; d < DIR; d++ ) {
        next = crt + dir[d];
        if ( viz[next.l][next.c] == 0 && mat[next.l][next.c] != 'D' )
            dfs( next );
    }
}

int main() {
    FILE *fin, *fout;
    char ch;
    int n, m, st, dr, mij, l, c, d;
    punct start, finish, crt, next;

    fin = fopen( "barbar.in", "r" );
    fscanf( fin, "%d%d", &n, &m );
    for ( l = 0; l <= n + 1; l++ ) {
        for ( c = 0; c <= m + 1; c++ ) {
            mat[l][c] = 'P';
            dist[l][c] = -1;
        }
    }
    fgetc( fin );
    for ( l = 1; l <= n; l++ ) {
        for ( c = 1; c <= m; c++ ) {
            ch = fgetc( fin );
            mat[l][c] = ch;
            if ( ch == 'I' )
                start = { l, c };
            else if ( ch == 'O' )
                finish = { l, c };
            if ( ch == 'D' ) {
                dist[l][c] = 0;
                q.push( { l, c } );
            }
        }
        fgetc( fin );
    }
    fclose( fin );

    while ( !q.empty() ) {
        crt = q.front();
        q.pop();

        for ( d = 0; d < DIR; d++ ) {
            next = crt + dir[d];
            if ( mat[next.l][next.c] != 'P' && dist[next.l][next.c] == -1 ) {
                dist[next.l][next.c] = dist[crt.l][crt.c] + 1;
                q.push( next );
            }
        }
    }

    st = -1;
    dr = dist[start.l][start.c] + 1;
    while ( dr - st > 1 ) {
        mij = (st + dr) / 2;
        for ( l = 0; l <= n + 1; l++ ) {
            for ( c = 0; c <= m + 1; c++ ) {
                if ( mat[l][c] == 'P' || mat[l][c] == '*' || dist[l][c] < mij )
                    viz[l][c] = -1;
                else
                    viz[l][c] = 0;
            }
        }

        dfs( start );

        if ( viz[finish.l][finish.c] == 1 )
            st = mij;
        else
            dr = mij;
    }

    fout = fopen( "barbar.out", "w" );
    fprintf( fout, "%d", st );
    fclose( fout );

    return 0;
}