Cod sursa(job #2083930)

Utilizator borscalinCalin-Stefan Georgescu borscalin Data 8 decembrie 2017 12:32:19
Problema Barbar Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.4 kb
#include <cstdio>
#include <iostream>
#include <queue>
#define NMAX 1000

using namespace std;

struct coord {
    int x, y;
    coord operator +(coord a) {
        return {x  + a.x, y + a.y};
    };
};

queue <coord> q;
coord dir[] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
char prison[1 + NMAX + 1][1 + NMAX + 1];
int dist[1 + NMAX + 1][1 + NMAX + 1];
bool vis[1 + NMAX + 1][1 + NMAX + 1];

int n, m, p2;
coord start, stop;

void add_to_q(coord p, int d, int b) {
    if (vis[p.x][p.y] == false && prison[p.x][p.y] != '*' && d >= b) {
        vis[p.x][p.y] = true;
        q.push(p);
        if (p2 == false)
            dist[p.x][p.y] = 1 + d;
    } else if (p2 == false && vis[p.x][p.y] == true && dist[p.x][p.y] > 1 + d)
        dist[p.x][p.y] = 1 + d;
}

void lee(int b) {
    for (int x = 1; x <= n; ++x)
        for (int y = 1; y <= m; ++y)
            vis[x][y] = false;
    while (!q.empty()) {
        coord p = q.front();
        vis[p.x][p.y] = true;
        q.pop();
        for (int i = 0; i < 4; ++i) {
            coord aux = p + dir[i];
            if (p2 == true)
                add_to_q(aux, dist[aux.x][aux.y], b);
            else
                add_to_q(aux, dist[p.x][p.y], b);
        }
    }
}

int bs() {
    int ans = 0;
    int st = 0, dr = NMAX * NMAX;
    while (st <= dr) {
        int mid = (st + dr) >> 1;
        q.push(start);
        lee(mid);
        if (vis[stop.x][stop.y] == true) {
            ans += mid;
            st = mid + 1;
        } else
            dr = mid - 1;
    }
    return (ans > 0) ? ans : -1;
}

int main(){
    FILE *f = fopen("barbar.in", "r");
    fscanf(f, "%d%d", &n, &m);
    char ch = fgetc(f);
    for (int x = 1; x <= n; ++x) {
        for (int y = 1; y <= m; ++y) {
            ch = fgetc(f);
            prison[x][y] = ch;
            if (ch == 'I')
                start = (coord) {x, y};
            else if (ch == 'O')
                stop = (coord) {x, y};
            else if (ch == 'D')
                q.push({x, y}), dist[x][y] = 0;
        }
        ch = fgetc(f);
    }
    fclose(f);
    p2 = false;
    for (int x = 0; x <= n + 1; ++x)
        vis[x][0] = vis[x][m + 1] = true;
    for (int y = 0; y <= m + 1; ++y)
        vis[0][y] = vis[n + 1][y] = true;
    lee(0);
    p2 = true;
    f = fopen("barbar.out", "w");
    fprintf(f, "%d", bs());
    fclose(f);
    return 0;
}