Cod sursa(job #1498633)

Utilizator tudorcomanTudor Coman tudorcoman Data 8 octombrie 2015 21:10:30
Problema Barbar Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3 kb

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <queue>

const char *in = "barbar.in";
const char *out = "barbar.out";
const short maxL = 1000;

class Casuta {
public:
    short x, y;
    Casuta() { }
    Casuta(short x, short y) {
        this->x = x, this->y = y;
    }
    Casuta operator + (const Casuta& other) {
        return Casuta(x + other.x, y + other.y);
    }
}dir[] = {
    Casuta(0, -1),
    Casuta(0, +1),
    Casuta(-1, 0),
    Casuta(+1, 0)
}, start, exit;

std :: queue<Casuta> C;
short N, M, minDist[1 + maxL + 1][1 + maxL + 1];
bool viz[1 + maxL + 1][1 + maxL + 1];

inline bool inMatrix(Casuta c) {
    return 1 <= c.x and c.x <= N and 1 <= c.y and c.y <= M;
}

bool sol(short nr) {
    if(minDist[start.x][start.y] == -2)
        return true;
    if(minDist[start.x][start.y] < nr)
        return false;
    memset(viz, 0, sizeof(viz));

    while(!C.empty())
        C.pop();

    C.push(start);
    viz[start.x][start.y] = 1;

    while(!C.empty()) {
        Casuta c = C.front();
        C.pop();
        for(register short k = 0; k < 4; ++ k) {
            Casuta v = c + dir[k];
            if(inMatrix(v) and minDist[v.x][v.y] >= nr and !viz[v.x][v.y]) {
                viz[v.x][v.y] = true;
                C.push(v);
            }
        }
    }

    return viz[exit.x][exit.y];
}

void Init();
void BFS() {
    while(!C.empty()) {
        Casuta c = C.front();
        C.pop();
        for(register short k = 0; k < 4; ++ k) {
            Casuta v = c + dir[k];
            if(inMatrix(v) and minDist[v.x][v.y] == -2 and !viz[v.x][v.y]) {
                minDist[v.x][v.y] = minDist[c.x][c.y] + 1;
                C.push(v);
                viz[v.x][v.y] = true;
            }
        }
    }
}

int main(void) {
    freopen(in, "r", stdin);
    freopen(out, "w", stdout);
    scanf("%hd %hd", &N, &M);
    Init();
    BFS();
    int st = 0, dr = N * M, mid, ans = -1;
    while(st <= dr) {
        mid = (st + dr) >> 1;
        if(sol(mid)) {
            ans = mid;
            st = mid + 1;
        } else
            dr = mid - 1;
    }
    printf("%d\n", ans);
    return 0;
}

void Init() {
    for(register short i = 0; i <= N + 1; ++ i)
        for(register short j = 0; j <= M + 1; ++ j)
            minDist[i][j] = -2;

    for(register short i = 0; i <= N + 1; ++ i) minDist[i][0] = minDist[i][M + 1] = -1;
    for(register short i = 0; i <= M + 1; ++ i) minDist[0][i] = minDist[N + 1][i] = -1;

    char ch = getc(stdin);
    for(register short i = 1; i <= N; ++ i, ch = getc(stdin))
        for(register short j = 1; j <= M; ++ j) {
            ch = getc(stdin);
            switch(ch) {
                case 'I': start = Casuta(i, j); break;
                case '*': minDist[i][j] = -1; break;
                case 'D': C.push(Casuta(i, j)); viz[i][j] = 1; minDist[i][j] = 0; break;
                case 'O': exit = Casuta(i, j);
                default: break;
            }
        }
}