Cod sursa(job #1498608)

Utilizator tudorcomanTudor Coman tudorcoman Data 8 octombrie 2015 20:39:18
Problema Barbar Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.72 kb

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

const char *in = "barbar.in";
const char *out = "barbar.out";
const int maxL = 1003;

class Casuta {
public:
    int x, y;
    Casuta() { }
    Casuta(int x, int 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;
int N, M, minDist[1 + maxL + 1][1 + maxL + 1];
bool viz[1 + maxL + 1][1 + maxL + 1];

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

    while(!C.empty()) {
        Casuta c = C.front();
        C.pop();
        for(register int k = 0; k < 4; ++ k) {
            Casuta v = c + dir[k];
            if(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 int k = 0; k < 4; ++ k) {
            Casuta v = c + dir[k];
            if(minDist[v.x][v.y] == -2) {
                minDist[v.x][v.y] = minDist[c.x][c.y] + 1;
                C.push(v);
            }
        }
    }
}

int main(void) {
    freopen(in, "r", stdin);
    freopen(out, "w", stdout);
    scanf("%d %d\n", &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 int i = 0; i <= N + 1; ++ i)
        for(register int j = 0; j <= M + 1; ++ j)
            minDist[i][j] = -2;

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

    char ch;
    for(register int i = 1; i <= N; ++ i, ch = getc(stdin))
        for(register int 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;
            }
        }
}