Pagini recente » Cod sursa (job #1019693) | Statistici Cojocaru Matei Nitu (UPB_Cojocaru_Matei_Nitu) | Cod sursa (job #1722160) | Cod sursa (job #1717062) | Cod sursa (job #1919592)
#include <fstream>
#include <queue>
#include <vector>
#include <cstring>
#define nmax 1005
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
int n, m, start_x, start_y, end_x, end_y, dist_from_dragon[nmax][nmax], how_to_here[nmax][nmax], near;
bool is_blocked[nmax][nmax], was_here[nmax][nmax];
queue < pair < int, int > > tail;
int d_x[] = {-1, 0, 1, 0};
int d_y[] = {0, 1, 0, -1};
inline bool is_ok(int x, int y) {
if (x < 1 or y < 1 or x > n or y > n or is_blocked[x][y] or was_here[x][y])
return false;
return true;
}
inline bool is_ok_two(int x, int y) {
if (x < 1 or y < 1 or x > n or y > n or is_blocked[x][y])
return false;
return true;
}
inline bool is_ok_three(int x2, int y2, int x, int y) {
if (how_to_here[x2][y2] < dist_from_dragon[x2][y2] and how_to_here[x2][y2] < how_to_here[x][y])
return true;
return false;
}
vector < int > my_vector;
void last_lee() {
memset(was_here, false, sizeof(was_here));
tail.push(make_pair(start_x, start_y));
was_here[start_x][start_y] = true;
how_to_here[start_x][start_y] = dist_from_dragon[start_x][start_y];
while (!tail.empty()) {
int x = tail.front().first;
int y = tail.front().second;
tail.pop();
for (int k = 0; k < 4; ++k) {
if (is_ok_two(x + d_x[k], y + d_y[k]))
if (!was_here[x + d_x[k]][y + d_y[k]]) {
how_to_here[x + d_x[k]][y + d_y[k]] = min(how_to_here[x][y], dist_from_dragon[x + d_x[k]][y + d_y[k]]);
was_here[x + d_x[k]][y + d_y[k]] = true;
tail.push(make_pair(x + d_x[k], y + d_y[k]));
}
else
if (is_ok_three(x + d_x[k], y + d_y[k], x, y)) {
how_to_here[x + d_x[k]][y + d_y[k]] = min(how_to_here[x][y], dist_from_dragon[x + d_x[k]][y + d_y[k]]);
tail.push(make_pair(x + d_x[k], y + d_y[k]));
}
if (x + d_x[k] == end_x and y + d_y[k] == end_y)
my_vector.push_back(1);
if (my_vector.size() == near)
break;
}
}
}
void dragon_lee() {
while (!tail.empty()) {
int x = tail.front().first;
int y = tail.front().second;
tail.pop();
for (int k = 0; k < 4; ++k)
if (is_ok(x + d_x[k], y + d_y[k])) {
was_here[x + d_x[k]][y + d_y[k]] = true;
dist_from_dragon[x + d_x[k]][y + d_y[k]] = dist_from_dragon[x][y] + 1;
tail.push(make_pair(x + d_x[k], y + d_y[k]));
}
}
}
void set_first() {
string x;
for (int i = 1; i <= n; ++i) {
fin >> x;
for (int j = 0; j < x.size(); ++j) {
if (x[j] == '*')
is_blocked[i][j + 1] = true;
if (x[j] == 'D') {
was_here[i][j + 1] = true;
tail.push(make_pair(i, j + 1));
}
if (x[j] == 'I') {
start_x = i;
start_y = j + 1;
}
if (x[j] == 'O') {
end_x = i;
end_y = j + 1;
}
}
}
}
void calculate() {
near = 4;
if (end_x - 1 < 1 or is_blocked[end_x - 1][end_y])
--near;
if (end_x + 1 > n or is_blocked[end_x + 1][end_y])
--near;
if (end_y - 1 < 1 or is_blocked[end_x][end_y - 1])
--near;
if (end_y + 1 > m or is_blocked[end_x][end_y + 1])
--near;
}
int main()
{
fin >> n >> m;
set_first();
calculate();
dragon_lee();
last_lee();
if (!was_here[end_x][end_y])
fout << "-1";
else
fout << how_to_here[end_x][end_y];
return 0;
}