Cod sursa(job #2082830)

Utilizator PondorastiAlex Turcanu Pondorasti Data 6 decembrie 2017 20:21:22
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.63 kb
#include <fstream>
#include <queue>

using namespace std;

struct Punctulet {
    int x, y;
}start, finish;

const int NMAX = 1e3;
char line[NMAX + 2];
int n, m, ans = -1;
bool zid[NMAX + 2][NMAX + 2];
int dragoni[NMAX + 2][NMAX + 2];
bool viz[NMAX + 2][NMAX + 2];
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
queue<Punctulet> d;

void read();
void bordare();

void bfs_dragon() {
    while (!d.empty()) {
        Punctulet p = d.front();
        d.pop();
        for (int i = 0; i < 4; ++i) {
            int x = p.x + dx[i];
            int y = p.y + dy[i];
            if(!zid[x][y] && dragoni[x][y] == 0) {
                dragoni[x][y] = dragoni[p.x][p.y] + 1;
                d.push({x, y});
            }
        }
    }
}

void clear() {
    for(int i = 1; i <= NMAX; ++i) {
        for(int j = 1; j <= NMAX; ++j)
            viz[i][j] = false;
    }
}

bool findExit(int distance) {
    if(dragoni[start.x][start.y] < distance || dragoni[finish.x][finish.y] < distance)
        return false;
    
    clear();
    queue<Punctulet> q;
    q.push(start);
    while (!q.empty()) {
        Punctulet p = q.front();
        q.pop();
        for(int i = 0; i < 4; ++i) {
            int x = p.x + dx[i];
            int y = p.y + dy[i];
            if(dragoni[x][y] >= distance && !zid[x][y] && !viz[x][y]) {
                viz[x][y] = true;
                if(finish.x == x && finish.y == y)
                    return true;
                q.push({x, y});
            }
        }
    }
    return false;
}

void cautareBinara() {
    int left = 1, right = n * m;
    while (left <= right) {
        int mid = (left + right) / 2;
        if(findExit(mid)) {
            ans = mid;
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
}

void solve() {
    ofstream cout("barbar.out");
    
    read();
    bordare();
    bfs_dragon();
    cautareBinara();
    
    cout << ans << "\n";
}

int main() {
    solve();
    return 0;
}

void read() {
    ifstream cin("barbar.in");
    
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) {
        cin >> line;
        for (int j = 0; j < m; ++j) {
            if(line[j] == 'D') {
                d.push({i, j + 1});
                zid[i][j + 1] = true;
            } else if(line[j] == '*') {
                zid[i][j + 1] = true;
            } else if(line[j] == 'I') {
                start = {i, j + 1};
            } else if(line[j] == 'O') {
                finish = {i, j + 1};
            }
        }
    }
}

void bordare() {
    for (int i = 0; i <= n + 1; ++i)
        zid[i][0] = zid[i][m + 1] = true;
    for (int j = 0; j <= m + 1; ++j)
        zid[0][j] = zid[n + 1][j] = true;
}