Cod sursa(job #2667546)

Utilizator EuAlexOtaku Hikikomori EuAlex Data 3 noiembrie 2020 17:06:23
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.78 kb
#include <cstdio>
#include <cstring>
#include <queue>
#include <climits>

using namespace std;

const int Nmax = 1005;

struct Poz {
    int x, y;
};

int n, m;
int start_x, start_y;
int final_x, final_y;
char s[Nmax];
int v[Nmax][Nmax];
bool viz[Nmax][Nmax];
queue <Poz> q;
int dx[] = {-1, 0, 1, 0},
    dy[] = {0, 1, 0, -1};

void bordare() {
    for(int i = 0; i <= n + 1; i ++) {
        v[i][0] = v[i][m + 1] = -2;
    }

    for(int j = 0; j <= m + 1; j ++) {
        v[0][j] = v[n + 1][j] = -2;
    }
}

void citire() {
    scanf("%d%d\n", &n, &m);

    for(int i = 1; i <= n; i ++) {
        fgets(s, 1005, stdin);

        int len = strlen(s);
        for(int j = 1; j <= len; j ++) {
            char ch = s[j - 1];

            if(ch == 'I') {
                start_x = i;
                start_y = j;
                v[i][j] = INT_MAX;
            }
            if(ch == 'O') {
                final_x = i;
                final_y = j;
                v[i][j] = INT_MAX;
            }
            if(ch == 'D') {
                q.push({i, j});
            }
            if(ch == '.') {
                v[i][j] = INT_MAX;
            }
            if(ch == '*') {
                v[i][j] = -2;
            }
        }
    }
}

void bfsDragoni() {
    while(!q.empty()) {
        for(int k = 0; k < 4; k ++) {
            if(v[q.front().x + dx[k]][q.front().y + dy[k]] == INT_MAX) {
                v[q.front().x + dx[k]][q.front().y + dy[k]] = v[q.front().x][q.front().y] + 1;
                q.push({q.front().x + dx[k], q.front().y + dy[k]});
            }
        }
        q.pop();
    }
}

void dfs(int x, int y, int dist) {
    viz[x][y] = 1;

    for(int k = 0; k < 4; k ++) {
        int newx = x + dx[k], newy = y + dy[k];
        if(viz[newx][newy] == 0 && v[newx][newy] >= 1 && v[newx][newy] >= dist) {
            dfs(newx, newy, dist);
        }
    }
}

int solveBinarySearch() {
    int left = 1, right = INT_MAX, last = -1;

    while(left <= right) {
        int med = (right - left) / 2 + left;

        for(int i = 1; i <= n; i ++) {
            for(int j = 1; j <= m; j ++) {
                viz[i][j] = 0;
            }
        }

        if(v[start_x][start_y] < med) {
            right = med - 1;
            continue;
        }

        dfs(start_x, start_y, med);

        if(viz[final_x][final_y] == true) {
            last = med;
            left = med + 1;
        } else {
            right = med - 1;
        }
    }

    return last;
}

void afisare() {
    for(int i = 1; i <= n; i ++) {
        for(int j = 1; j <= m; j ++) {
            printf("%d ", v[i][j]);
        }
        printf("\n");
    }
}

int main() {
    freopen("barbar.in", "r", stdin);
    freopen("barbar.out", "w", stdout);

    citire();
    bordare();
    bfsDragoni();
    printf("%d", solveBinarySearch());

    return 0;
}