Cod sursa(job #2017553)

Utilizator savigunFeleaga Dragos-George savigun Data 1 septembrie 2017 17:09:32
Problema Barbar Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.02 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
using namespace std;

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

struct Waypoint {
    int x, y, d;
};

struct Cell {
    int x, y;
};

int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};

int r, c;
Cell start, ex;
int dist[1001][1001], best[1001][1001];
bool pushed[1001][1001];
char a[1001][1001];
queue<Cell> q;
queue<Cell> road;


void calculate_distances() {
    while (!q.empty()) {
        Cell w = q.front(); q.pop();
        int x = w.x, y = w.y;
        for (int k = 0; k < 4; ++k) {
            int i = x + dx[k];
            int j = y + dy[k];
            if (i >= 1 && i <= r && j >= 1 && j <= c) {
                if ((a[i][j] == '.' || a[i][j] == 'I' || a[i][j] == 'O') && dist[i][j] == 0) {
                    dist[i][j] = dist[x][y] + 1;
                    q.push({i, j});
                }
            }
        }
    }
}


void solve() {
    road.push({start.x, start.y});
    best[start.x][start.y] = dist[start.x][start.y];

    while (!road.empty()) {
        Cell w = road.front(); road.pop();
        int x = w.x, y = w.y, d = best[x][y];

        pushed[x][y] = false;

        for (int k = 0; k < 4; ++k) {
            int i = x + dx[k];
            int j = y + dy[k];
            if (i >= 1 && i <= r && j >= 1 && j <= c) {
                if (dist[i][j] != 0) {
                    bool push = false;

                    if (best[i][j] == 0) { // first time here
                        push = true;
                        best[i][j] = min(d, dist[i][j]);
                    } else { // not first time
                        if (d > dist[i][j]) continue; // bigger dist than biggest possible
                        // else
                        if (d > best[i][j]) {
                            push = true;
                            best[i][j] = d;
                        }
                    }


                    if (i == ex.x && j == ex.y) continue;

                    if (push && !pushed[i][j]) {
                        road.push({i, j});
                        pushed[i][j] = true;
                    }
                }
            }
        }
    }
}


int main()
{
    in >> r >> c;
    for (int i = 1; i <= r; ++i) {
        for (int j = 1; j <= c; ++j) {
            in >> a[i][j];
            if (a[i][j] == 'I') {
                start = {i, j};
            } else if (a[i][j] == 'O') {
                ex = {i, j};
            } else if (a[i][j] == 'D') {
                q.push({i, j});
            }
        }
    }

    calculate_distances();

    solve();

    if (best[ex.x][ex.y] == 0) out << -1; else out << best[ex.x][ex.y];

    /*for (int i = 1; i <= r; ++i) {
        for (int j = 1; j <= c; ++j) {
            if (dist[i][j] == 0) {
                cout << a[i][j] << " ";
            } else {
                cout << best[i][j] << " ";
            }
        }
        cout << endl;
    }*/


    return 0;
}