Cod sursa(job #2210987)

Utilizator ContDeRacistAliniateEBlat ContDeRacist Data 8 iunie 2018 23:31:39
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.42 kb
#include <fstream>
#include <deque>
using namespace std;

ifstream cin("barbar.in");
ofstream cout("barbar.out");

const int N = 1e3 + 7;

pair < int, int > q[N * N], start, finish;

int st, dr(-1), n, m;

int dl[4] = {-1, 0, 1, 0};
int dc[4] = {0, 1, 0, -1};

bool visit[N][N];
int dist[N][N], dist01[N][N];

string s[N];

void boardare() {
    for (int i = 0; i <= n + 1; ++i) {
        visit[i][0] = visit[i][m + 1] = true;
    }
    for (int j = 0; j <= m + 1; ++j) {
        visit[0][j] = visit[n + 1][j] = true;
    }
}

void bfs() {
    while (st <= dr) {
        pair < int, int > x = q[st++];
        int _xf, _xs;
        for (int i = 0; i < 4; ++i) {
            _xf = x.first + dl[i];
            _xs = x.second + dc[i];
            if (!visit[_xf][_xs]) {
                dist[_xf][_xs] = dist[x.first][x.second] + 1;
                q[++dr] = make_pair(_xf, _xs);
                visit[_xf][_xs] = true;
            }
        }
    }
}

void citire() {
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) {
        cin >> s[i];
        for (int j = 1; j <= m; ++j) {
            if (s[i][j - 1] == '*') {
                visit[i][j] = true;
            }
            if (s[i][j - 1] == 'I') {
                start = make_pair(i, j);
            }
            if (s[i][j - 1] == 'O') {
                finish = make_pair(i, j);
            }
            if (s[i][j - 1] == 'D') {
                q[++dr] = make_pair(i, j);
            }
        }
    }
}

void refatot() {
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            visit[i][j] = false;
        }
    }
}

void refacitirev() {
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (s[i][j - 1] == '*') {
                visit[i][j] = true;
            }
        }
    }
}

void reset() {
    refatot();
    refacitirev();
}

void bfs01() {
    deque < pair < int, int > > dq;
    dq.push_front(start);
    visit[start.first][start.second] = true;
    dist01[start.first][start.second] = dist[start.first][start.second];
    while (!dq.empty()) {
        pair < int, int > x = dq.front();
        dq.pop_front();
        int _xf, _xs;
        for (int i = 0; i < 4; ++i) {
            _xf = x.first + dl[i];
            _xs = x.second + dc[i];
            if (!visit[_xf][_xs]) {
                if (dist01[x.first][x.second] <= dist[_xf][_xs]) {
                    dist01[_xf][_xs] = dist01[x.first][x.second];
                    dq.push_front(make_pair(_xf, _xs));
                }
                else {
                    dist01[_xf][_xs] = dist[_xf][_xs];
                    dq.push_back(make_pair(_xf, _xs));
                }
                visit[_xf][_xs] = true;
            }
        }
    }
}

void afiseste() {
    if (visit[finish.first][finish.second]) {
        cout << dist01[finish.first][finish.second] << "\n";
        return;
    }
    cout << "-1\n";
}

int main()
{
    citire();
    boardare();
    bfs();
    reset();
    bfs01();
    afiseste();
    ///ce drq e cu main-ul asta nu stiu dar vad ca arata shmek3r asa ca il pastrez (Am scris asa ca a spus vsft ca o gluma de genul ca o functie sa nu aiba mai mult de 25 de linii de cod si eu o iau in serios esti gay la revedere) + am de injurat pe Serban Cercelescu pentru ca este gay si o merita decdicatie speciala pentru debei !
    return 0;
}