Pagini recente » Cod sursa (job #568601) | Cod sursa (job #2548773) | Cod sursa (job #2917387) | Cod sursa (job #1982193) | Cod sursa (job #2944954)
#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;
}