Cod sursa(job #1745028)

Utilizator Tiberiu02Tiberiu Musat Tiberiu02 Data 20 august 2016 23:40:27
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.66 kb
# include <iostream>
# include <fstream>

# include <stdio.h>
# include <stdlib.h>

# include <queue>
# include <vector>
# include <string.h>

using namespace std;

struct point {
    int x, y, d;
};

queue<struct point> dragoni;
struct point org, dst;

# define MAX_N 1000
# define MAX_M 1000

int mat[1 + MAX_N + 1][1 + MAX_M + 1];
int cpy[1 + MAX_N + 1][1 + MAX_M + 1];

# define BLOCKED -1
# define UNSET 100000000

struct point newPoint( int x, int y, int d ) {
    struct point aux;

    aux.x = x;
    aux.y = y;
    aux.d = d;

    return aux;
}

struct point newPoint( int x, int y ) {
    struct point aux;

    aux.x = x;
    aux.y = y;
    aux.d = 0;

    return aux;
}

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

bool path( int d ) {
    queue<struct point> dfs;
    int i;

    memcpy( cpy, mat, sizeof( cpy ) );
    dfs.push( org );

    # define t dfs.front()
    while ( dfs.size() && ( t.x != dst.x || t.y != dst.y ) ) {
        if ( cpy[t.x][t.y] != BLOCKED && cpy[t.x][t.y] >= d )
            for ( i = 0; i < 4; i ++ )
                dfs.push( newPoint( t.x + dx[i], t.y + dy[i] ) );

        cpy[t.x][t.y] = BLOCKED;
        dfs.pop();
    }
    # undef t

    return dfs.size() > 0;
}

int main() {
    ifstream fin( "barbar.in" );
    ofstream fout( "barbar.out" );

    int n, m, i, j;
    char ch;

    fin >> n >> m;

    for ( i = 1; i <= n; i ++ )
        for ( j = 1; j <= m; j ++ ) {
            fin >> ch;

            mat[i][j] = UNSET;
            switch ( ch ) {
            case '*':
                mat[i][j] = BLOCKED;
                break;
            case 'D':
                dragoni.push( newPoint( i, j, 0 ) );
                break;
            case 'I':
                org = newPoint( i, j );
                break;
            case 'O':
                dst = newPoint( i, j );
                break;
            }
        }

    for ( i = 0; i <= n + 1; i ++ )
        mat[i][0] = mat[i][m + 1] = BLOCKED;
    for ( i = 0; i <= m + 1; i ++ )
        mat[0][i] = mat[n + 1][i] = BLOCKED;

    while ( dragoni.size() ) {
        # define t dragoni.front()
        if ( mat[t.x][t.y] == UNSET ) {
            for ( i = 0; i < 4; i ++ )
                dragoni.push( newPoint( t.x + dx[i], t.y + dy[i], t.d + 1 ) );
            mat[t.x][t.y] = t.d;
        }
        dragoni.pop();
        # undef t
    }

    int pos, pas;
    pos = -1;
    for ( pas = ( 1 << 20 ); pas > 0; pas >>= 1 ){
        if ( path( pos + pas ) == 1 )
            pos += pas;
    }

    fout << pos;

    fin.close();
    fout.close();

    return 0;
}