Cod sursa(job #761824)

Utilizator SchumiDumitru Andrei Georgian Schumi Data 27 iunie 2012 15:26:51
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.49 kb
#include <cstdio>
#include <queue>
using namespace std;


const int N = 1005;
queue <pair <int, int> > q;
const int dl[4] = {1, 0, -1, 0};
const int dc[4] = {0, 1, 0, -1};
int lin, col, n, m, mat[N][N], mat2[N][N], sx, sy, fx, fy;
bool viz[N][N];
char c;

void calculeaza_distante()
{
    int i;
    while(!q.empty()) {
        for(i = 0; i < 4; ++i) {
            lin = q.front().first + dl[i];
            col = q.front().second + dc[i];
            if(lin > 0 && lin <= n && col > 0 && col <= m && mat[lin][col] != -1 && !viz[lin][col]) {
                mat2[lin][col] = mat2[q.front().first][q.front().second] + 1;
                viz[lin][col] = 1;
                q.push(make_pair(lin, col));
            }
        }
        q.pop();
    }
}

int verifica(int x)
{
    int i, j;
    queue <pair <int, int> > q;
    for(i = 1; i <= n; ++i)
        for(j = 1; j <= n; ++j)
            viz[i][j] = 0;
    viz[sx][sy] = 1;
    if(mat2[sx][sy] < x)
        return 0;
    q.push(make_pair(sx, sy));
    while(!q.empty()) {
        for(i = 0; i < 4; ++i) {
            lin = q.front().first + dl[i];
            col = q.front().second + dc[i];
            if(lin > 0 && lin <= n && col > 0 && col <= m && !viz[lin][col] && mat[lin][col] != -1 && mat2[lin][col] >= x) {
                if(lin == fx && col == fy)
                    return 1;
                viz[lin][col] = 1;
                q.push(make_pair(lin, col));
            }
        }
        q.pop();
    }
    return 0;
}

int cauta_solutie()
{
    int p = 0, u = n * m, mij, sol = -1;
    while(p <= u) {
        mij = (p + u) / 2;
        if(verifica(mij)) {
            sol = mij;
            p = mij + 1;
        }
        else u = mij - 1;
    }
    return sol;
}

int main()
{
    int i, j;
    freopen ("barbar.in", "r", stdin);
    freopen ("barbar.out", "w", stdout);
    scanf("%d %d", &n, &m);
    scanf("%c", &c);
    for(i = 1; i <= n; ++i) {
        for(j = 1; j <= m; ++j) {
            scanf("%c", &c);
            switch (c) {
                case('*'): {mat[i][j] = -1; break;}
                case('D'): {mat[i][j] = 1, q.push(make_pair(i, j)), viz[i][j] = 1; break;}
                case('I'): {sx = i, sy = j; break;}
                case('O'): {fx = i, fy = j; break;}
            }
        }
        scanf("%c", &c);
    }
    calculeaza_distante();
   /* for(i = 1; i <= n; ++i) {
        for(j = 1; j <= m; ++j)
            fprintf(stderr, "%d ", mat2[i][j]);
        fprintf(stderr, "\n");
    } */
    printf("%d\n", cauta_solutie());
    return 0;
}