Cod sursa(job #1919453)

Utilizator DeehoroEjkoliPop Darian DeehoroEjkoli Data 9 martie 2017 19:32:45
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.22 kb
#include <fstream>
#include <queue>
#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];

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;
}

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]));
                    }
    }
}

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;
            }
        }
    }
}

int main()
{
    fin >> n >> m;
    set_first();
    dragon_lee();
    last_lee();
    if (!was_here[end_x][end_y])
        fout << "-1";
    else
        fout << how_to_here[end_x][end_y];
    return 0;
}