Cod sursa(job #761795)

Utilizator SchumiDumitru Andrei Georgian Schumi Data 27 iunie 2012 14:40:18
Problema Barbar Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.16 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 && !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;
    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);
    for(i = 1; i <= n; ++i)
        for(j = 1; j <= m; ++j) {
            scanf(" %c ", &c);
            switch (c) {
                case('*'): mat[i][j] = -1;
                case('D'): {mat[i][j] = 1, q.push(make_pair(i, j));}
                case('I'): {sx = i, sy = j;}
                case('O'): {fx = i, fy = j;}
            }
        }
    calculeaza_distante();
    printf("%d\n", cauta_solutie());
    return 0;
}