Cod sursa(job #931451)

Utilizator crisbodnarCristian Bodnar crisbodnar Data 28 martie 2013 11:27:10
Problema Barbar Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.39 kb
#include <iostream>
#include <fstream>
#include <iomanip>

#define INF 0x3f3f3f3f

using namespace std;

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

int n, m, li, ci, lf, cf, a[1005][1005], b[1005][1005], st, dr, nr;
short l[1000002], c[1000002];

const short di[] = {1, -1, 0, 0},
            dj[] = {0, 0, 1, -1};

void Afisare();

void Citire(){

    fin>>n>>m; fin.get();

    char x; int contor = 0;
    for(int i=1; i<=n; i++){
        for(int j=1; j<=m; j++){
            fin.get(x);
                 if(x == '.') a[i][j] = INF;
            else if(x == 'D') l[++dr] = i, c[dr] = j, a[i][j] = 0;
            else if(x == '*') a[i][j] = -1;
            else if(x == 'I') li = i, ci = j, a[i][j] = INF;
            else if(x == 'O') lf = i, cf = j, a[i][j] = INF;
        }
        fin.get();
    }

}

void Lee_drago(){
    st = 1;
    while(st <= dr){
        int i = l[st], j = c[st];
        for(int k=0; k<4; k++){
            int ii = i + di[k], jj = j + dj[k];
            if(a[ii][jj] == INF){
                dr++;
                l[dr] = ii, c[dr] = jj;
                a[ii][jj] = a[i][j] + 1;
            }
        }
        st++;
    }
}

void Bordare(){
    for(int i=0; i<=n+1; i++)
        b[i][0] = b[i][m+1] = INF;
    for(int j=0; j<=m+1; j++)
        b[0][j] = b[n+1][j] = INF;
}

int ok(int d){
    nr++;
    int st = 1, dr = 1;
    l[dr] = li, c[dr] = ci;
    b[li][ci] = nr;
    while(st <= dr){
        int i = l[st], j = c[st];
        for(int k=0; k<4; k++){
            int ii = i + di[k], jj = j + dj[k];
            if(a[ii][jj] >= d && b[ii][jj] < nr){
                dr++;
                l[dr] = ii, c[dr] = jj;
                b[ii][jj] = nr;
                if(ii = lf && jj == cf){
                    break; break;
                }
            }
        }
        st++;
    }
    return (b[lf][cf] == nr);
}

void Rezolvare(){
    st = -1, dr = a[li][ci];
    int m;
    while(dr - st > 1){
        m = (dr + (st-dr)/2);
        if(ok(m)) st = m;
        else dr = m;
    }
    if(dr == 0) fout<<-1;
    else fout<<m;
}

int main()
{
    Citire();
    Lee_drago();
    Bordare();
    Rezolvare();
    //Afisare();
    return 0;
}

void Afisare(){
    for(int i=1; i<=n; i++){
        for(int j=1; j<=m; j++)
            fout<<setw(2)<<b[i][j]<<" ";
        fout<<'\n';
    }


}