Cod sursa(job #2944954)

Utilizator MAlex2019Melintioi George Alexandru MAlex2019 Data 23 noiembrie 2022 10:20:49
Problema Barbar Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.95 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

ifstream fin("barbar.in");
ofstream fout("barbar.out");

typedef pair<int,int> cell;

const int maxdim = 1000;
const int BORDER = -1;

cell startpos, endpos;
vector<cell> dragons;
int world[maxdim + 2][maxdim + 2];
int aux[maxdim + 2][maxdim + 2];
int mars[maxdim + 2][maxdim + 2];
cell dirs[4] = {cell(-1,0), cell(0,1), cell(1,0), cell(0,-1)};

cell operator+(const cell &a, const cell &b) {
    return cell(a.first + b.first, a.second + b.second);
}

void distDragons(int dist) {
    int add = -1;
    for (cell dragon: dragons) {
        cell tl = cell(max(1,dragon.first-dist), max(1,dragon.second-dist));
        cell br = cell(min(maxdim,dragon.first + dist), min(maxdim,dragon.second + dist));
        mars[tl.first][tl.second] += add;
        mars[br.first + 1][tl.second] -= add;
        mars[tl.first][br.second + 1] -= add;
        mars[br.first + 1][br.second + 1] += add;
    }
    for (int i = 1; i < maxdim + 2; i++)
        for (int j = 1; j < maxdim + 2; j++) {
            mars[i][j] += mars[i - 1][j] + mars[i][j - 1] - mars[i - 1][j - 1];
            aux[i][j] += mars[i][j];
        }
}

bool isValid(int dist) {
    for (int i = 0; i < maxdim + 2; i++)
        for (int j = 0; j < maxdim + 2; j++) {
            aux[i][j] = world[i][j];
            mars[i][j] = 0;
        }
    distDragons(dist);
    if (aux[startpos.first][startpos.second] < 0)
        return false;
    queue<cell> coada;
    coada.push(startpos);
    while (!coada.empty()) {
        cell curr = coada.front();
        coada.pop();
        if (curr == endpos)
            return true;
        for (cell dir: dirs) {
            cell update = curr + dir;
            if (aux[update.first][update.second] == 0)
                coada.push(update);
        }
        aux[curr.first][curr.second] = 1;
    }
    return false;
}

int binarySearch(int left, int right) {
    if (right - left < 2)
        return isValid(right) ? right : left;
    int mid = (left + right)/2;
    if (isValid(mid))
        return binarySearch(mid, right);
    return binarySearch(left, mid - 1);
}

int main() {
    int r, c;
    fin >> r >> c;
    fin.get();
    for (int i = 1; i <= r; i++) {
        for (int j = 1; j <= c; j++) {
            char ch = fin.get();
            cell current = cell(i,j);
            if (ch == '*')
                world[i][j] = BORDER;
            else if (ch == 'D')
                dragons.push_back(current);
            else if (ch == 'I')
                startpos = current;
            else if (ch == 'O')
                endpos = current;
        }
        fin.get();
    }
    for (int i = 0; i < r + 2; i++)
        world[i][0] = world[i][c + 1] = BORDER;
    for (int j = 0; j < c + 2; j++)
        world[0][j] = world[r + 1][j] = BORDER;

    fout << binarySearch(1, min(r,c)) + 1 << '\n';

    return 0;
}