Cod sursa(job #974587)

Utilizator Kira96Denis Mita Kira96 Data 17 iulie 2013 16:49:09
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.55 kb
#include<cstdio>
#include<cstring>
using namespace std;
FILE*f=fopen("barbar.in","r");
FILE*g=fopen("barbar.out","w");
 
int di[4] = {-1,1,0,0};
int dj[4] = {0,0,-1,1};
int i,j,iinit,jinit,ifinal,jfinal,A[1024][1024],nrc,C[2][1024 * 1024];
int N,M,p,u,d,ic,jc,iv,jv,m;
char x,viz[1024][1024];
 
inline void precalculare() {
     
    p = 1; u = nrc;
    while ( p <= u ){
        ic = C[0][p]; jc = C[1][p];
         
        for ( d = 0 ; d < 4 ; ++d ){
            iv = ic + di[d]; jv = jc + dj[d];
            if ( iv >= 1 && iv <= N && jv >= 1 && jv <= M && A[iv][jv] == -1 ){
                ++u;
                C[0][u] = iv;
                C[1][u] = jv;
                A[iv][jv] = A[ic][jc] + 1;
            }
             
        }
        ++p;
    }
}
 
int coada(int dist) {
    int p = 1;
    int u = 1;
    C[0][1] = iinit; C[1][1] = jinit;
    memset(viz,0,sizeof(viz)); int ho = 0;
    if ( A[iinit][jinit] < dist )
        return ho;
     
    while ( p <= u && (!ho) ) {
        ic = C[0][p]; jc = C[1][p];
         
        for ( d = 0 ; d < 4 ; ++d ){
            iv = ic + di[d]; jv = jc + dj[d];
             
            if ( iv >= 1 && iv <= N && jv >= 1 && jv <= M && ( ! viz[iv][jv] ) && A[iv][jv] >= dist ){
                ++u;
                C[0][u] = iv;
                C[1][u] = jv;
                viz[iv][jv] = 1;
                if ( iv == ifinal && jv == jfinal ){
                    ho = 1;
                    break;
                }
            }
             
        }
        ++p;
    }
    return ho;
     
}
 
int main () {
     
    fscanf(f,"%d %d\n",&N,&M);
    for( i = 1 ; i <= N ; ++i ){
        for ( j = 1 ; j <= M ; ++j ){
            fscanf(f,"%c",&x);
            if ( x == 'I' ) iinit = i, jinit = j,A[i][j] = -1;
            else    if ( x == 'D' ) {C[0][++nrc] = i; C[1][nrc] = j;}
            else    if ( x == '*' ) A[i][j] = -2;
            else    if ( x == '.' ) A[i][j] = -1;
            else    if ( x == 'O' ) A[i][j] = -1, ifinal = i,jfinal = j;
        }
        fscanf(f,"\n");
    }
     
    precalculare();
     
    p = 0 ; u = N * M;
     
    while ( p <= u ) {
         
        m = p + ( u - p ) / 2;
         
        // daca da este 1 se poate traversa la o distanta mai mare sau egala decat m
         
        if ( coada( m ) )
            p = m + 1;
        else
            u = m - 1;
         
    }
    if ( u < 0 ) fprintf(g,"-1\n");
    else
        fprintf(g,"%d\n",u);
     
    fclose(f);
    fclose(g);
    return 0;
}