Cod sursa(job #2015800)

Utilizator Alex18maiAlex Enache Alex18mai Data 27 august 2017 15:27:49
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.49 kb
#include <fstream>
#include <queue>

using namespace std;

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

queue <pair<int,int>> Q_drag;
queue <pair<int,int>> Q_test;

bool cant[1005][1005];
bool cant_drag[1005][1005];
int drag[1005][1005];
bool test[1005][1005];

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

int biggest_2_power (int nr){
    int i=1;
    while (true){
        if (i > nr){
            return i/2;
        }
        i *= 2;
    }
}

bool can (int MIN, pair<int,int> start, pair<int,int> end, int n, int m){
    for (int i=1; i<=n; i++){
        for (int j=1; j<=m; j++){
            test[i][j] = false;
        }
    }
    while(!Q_test.empty()){
        Q_test.pop();
    }
    Q_test.push(start);
    test[start.first][start.second] = true;
    if (drag[start.first][start.second] < MIN){
        return false;
    }
    while (!Q_test.empty()){
        pair<int , int> cur;
        cur.first = Q_test.front().first;
        cur.second = Q_test.front().second;
        Q_test.pop();
        for (int i=1; i<=4; i++){
            int x_now = cur.first + dx[i];
            int y_now = cur.second + dy[i];
            if (x_now < 1 || x_now > n || y_now < 1 || y_now > m){
                continue;
            }
            if (cant[x_now][y_now] == true){
                continue;
            }
            if (drag[x_now][y_now] >= MIN && test[x_now][y_now] == false){
                test[x_now][y_now] = true;
                Q_test.push(make_pair(x_now, y_now));
            }
        }
    }
    return test[end.first][end.second];
}

int main() {
    int n, m;
    cin>>n>>m;
    pair<int,int> start;
    pair<int,int> end;
    for (int i=1; i<=n; i++){
        for (int j=1; j<=m; j++){
            drag[i][j] = 1e9;
        }
    }
    for (int i=1; i<=n; i++){
        string s;
        cin>>s;
        for (int j=0; j<m; j++){
            if (s[j] == 'D'){
                Q_drag.push(make_pair(i , j + 1));
                drag[i][j+1] = 0;
                cant[i][j+1] = true;
            }
            if (s[j] == '*'){
                cant[i][j+1] = true;
                cant_drag[i][j+1] = true;
            }
            if (s[j] == 'I'){
                start.first = i;
                start.second = j + 1;
            }
            if (s[j] == 'O'){
                end.first = i;
                end.second = j + 1;
            }
        }
    }
    while (!Q_drag.empty()){
        pair<int , int> cur;
        cur.first = Q_drag.front().first;
        cur.second = Q_drag.front().second;
        Q_drag.pop();
        for (int i=1; i<=4; i++){
            int x_now = cur.first + dx[i];
            int y_now = cur.second + dy[i];
            if (x_now < 1 || x_now > n || y_now < 1 || y_now > m){
                continue;
            }
            if (cant_drag[x_now][y_now] == true){
                continue;
            }
            if (drag[x_now][y_now] > drag[cur.first][cur.second] + 1){
                drag[x_now][y_now] = drag[cur.first][cur.second] + 1;
                Q_drag.push(make_pair(x_now, y_now));
            }
        }
    }
    /*for (int i=1; i<=n; i++){
        for (int j=1; j<=m; j++){
            cout<<drag[i][j]<<" ";
        }
        cout<<'\n';
    }*/
    int beg = biggest_2_power (n * m);
    int sol = 0;
    for (int step = beg; step > 0; step >>= 1){
        if ( sol + step < n * m && can(sol + step, start, end, n, m)){
            sol += step;
        }
    }
    if (sol == 0){
        cout<<-1;
    }
    else{
        cout<<sol;
    }
    return 0;
}