Cod sursa(job #90006)

Utilizator sandyxpSanduleac Dan sandyxp Data 8 octombrie 2007 12:10:10
Problema Barbar Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.53 kb
#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;

#define FIN "barbar.in"
#define FOUT "barbar.out"
#define MAXN 1000
#define INF 0x3f3f3f3f

struct punct { int x, y; };

int n, m, q, q0, cc;
punct C[2][16*MAXN*MAXN], st, fin;
char A[MAXN+2][MAXN+2];
int D[MAXN+2][MAXN+2], M[MAXN+2][MAXN+2];

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



template <typename fn>
void lee(fn _comp, int D[][MAXN+2]) {
    int x, y;
    while (q) {
        for (int p=0; p<q; ++p) {
            for (int i=0; i<4; ++i) {
                x=C[cc][p].x + dx[i], y = C[cc][p].y + dy[i];
                if (A[x][y] && A[x][y] != '*' &&
                        _comp(D [C[cc][p].x][C[cc][p].y]+1, D[x][y])) {
                    // e mai avantajos sa venim cu noua distanta
                    C[!cc][q0++] = (punct) { x, y };
                    D[x][y] = D [C[cc][p].x][C[cc][p].y] + 1;
                }
            }
        }
        q = q0; q0 = 0;
        cc = !cc;
    }
}

void lee2() {
    int x, y;
    while (q) {
        for (int p=0; p<q; ++p) {
            for (int i=0; i<4; ++i) {
                x=C[cc][p].x + dx[i], y = C[cc][p].y + dy[i];
                if (A[x][y] && A[x][y] != '*' &&
                        greater<int>()(min(M [C[cc][p].x][C[cc][p].y], D[x][y]), M[x][y])) {
                    // e mai mare distanta minima din tot lantul parcurs..deci go for it..
                    C[!cc][q0++] = (punct) { x, y };
                    M[x][y] = min(M [C[cc][p].x][C[cc][p].y], D[x][y]);
                }
            }
        }
        q = q0; q0 = 0;
        cc = !cc;
    }
}

void part1()
{
    int i, j;
    freopen(FIN, "r", stdin);
    freopen(FOUT,"w",stdout);
    scanf("%d %d\n", &n, &m);
    // *=perete, .=loc liber de camping, D=dragon, I=de unde pleaca prostu, O=target
    memset(D, INF, sizeof(D));
    for (i=1; i<=n; ++i) {
        for (j=1; j<=m; ++j) {
            scanf("%c", &A[i][j]);
            if (A[i][j] == 'I')
                st = (punct) { i, j };
            else if (A[i][j] == 'O')
                fin = (punct) { i, j };
            else if (A[i][j] == 'D')
                C[cc][q++] = (punct) { i, j }, D[i][j] = 0;
        }
        scanf("\n");
    }
}

int main()
{
    part1();
    lee(std::less<int>(), D);
    // cand eftemie a ajuns pe poz (i, j), M[i][j] = min D[ik][jk] dp fiecare
    // casuta parcursa pana acolo. M[fin.x][fin.y] tre sa fie max...
    M[fin.x][fin.y] = -1;
    C[cc=0][q++] = st; M[st.x][st.y] = D[st.x][st.y];
    lee2();
    printf("%d\n", M[fin.x][fin.y]);
    return 0;
}