Cod sursa(job #1498960)

Utilizator tudorcomanTudor Coman tudorcoman Data 9 octombrie 2015 22:14:58
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.65 kb

#include <cstring>
#include <string>
#include <fstream>
#include <queue>
using namespace std;

const int maxL = 1000 + 2;
int D[maxL][maxL], N, M;

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(this->x + other.x, this->y + other.y);
    }

    bool inside() {
        return 1 <= x and x <= N and 1 <= y and y <= M;
    }

}Enter, Exit, dir[] = {
Casuta(0, -1),
Casuta(0, +1),
Casuta(-1, 0),
Casuta(+1, 0)
};

queue<Casuta> C;

bool ok(int n) {
    bool viz[maxL][maxL];
    for(register int i = 0; i < maxL; ++ i)
        for(register int j = 0; j < maxL; ++ j)
            viz[i][j] = false;

    viz[Enter.x][Enter.y] = true;
    C.push(Enter);
    while(!C.empty()) {
        Casuta c = C.front();
        C.pop();
        for(register int k = 0; k < 4; ++ k) {
            Casuta v = c + dir[k];
            if(v.inside() and !viz[v.x][v.y] and n <= D[v.x][v.y]) {
                C.push(v);
                viz[v.x][v.y] = 1;
            }
        }
    }

    return viz[Exit.x][Exit.y];
}
int main() {
    ifstream cin("barbar.in");
    ofstream cout("barbar.out");

    cin >> N >> M;

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

    for(register int i = 1; i <= N; ++ i)
        for(register int j = 1; j <= M; ++ j)
            D[i][j] = -2;

    for(register int i = 1; i <= N; ++ i) {
        string lin;
        cin >> lin;
        for(register int j = 1; j <= M; ++ j) {
            switch(lin[j - 1]) {
                case 'I': Enter = Casuta(i, j); break;
                case 'O': Exit = Casuta(i, j); break;
                case 'D': C.push(Casuta(i, j)); D[i][j] = 0; break;
                case '*': D[i][j] = -1;
            }
        }
    }

    /// BFS pentru calculare D
    while(!C.empty()) {
        Casuta c = C.front();
        C.pop();
        for(register int k = 0; k < 4; ++ k) {
            Casuta vec = c + dir[k];
            if(vec.inside() and (D[c.x][c.y] + 1 < D[vec.x][vec.y] || D[vec.x][vec.y] == -2))
                D[vec.x][vec.y] = D[c.x][c.y] + 1, C.push(vec);
        }
    }

    int sol = 0, step, Limit = min(D[Exit.x][Exit.y], D[Enter.x][Enter.y]), last = -1;
    for(step = 1; (step << 1) <= Limit; step <<= 1);
    for( ; step ; step >>= 1)
        if(sol + step <= Limit and ok(sol + step))
            sol += step, last = sol;

    cout << last << '\n';
    cin.close();
    cout.close();
    return 0;
}