Cod sursa(job #2370164)

Utilizator andreisontea01Andrei Sontea andreisontea01 Data 6 martie 2019 10:58:06
Problema Barbar Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.85 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1005;

int n, m, sx, sy, fx, fy;
char harta[MAXN][MAXN];

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

#define x first
#define y second

void pars(){
    string s;
    getline(fin, s);
    for(int i = 1; i <= n; ++i){
        getline(fin, s);
        for(int j = 0; j <= m; ++j){
            harta[i][j + 1] = s[j];
            if(s[j] == 'I'){
                sx = i;
                sy = j + 1;
            }
            if(s[j] == 'O'){
                fx = i;
                fy = j + 1;
            }
        }
    }
}

int drag[MAXN][MAXN];
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
queue<pair<int, int> >q;

bool okd(int cx, int cy){
    if(cx > 0 && cx <= n && cy > 0 && cy <= m){
        if(harta[cx][cy] != '*')
            return 1;
        return 0;
    }
    return 0;
}

void expand(){
    for(int i = 1; i <= n; ++i){
        for(int j = 1; j <= m; ++j){
            drag[i][j] = 1e9;
            if(harta[i][j] == 'D'){
                drag[i][j] = 0;
                q.push(make_pair(i, j));
            }
        }
    }
    while(!q.empty()){
        pair<int, int> cel = q.front();
        q.pop();
        for(int d = 0; d < 4; ++d){
            int nx = cel.x + dx[d], ny = cel.y + dy[d];
            if(okd(nx, ny)){
                int step = drag[cel.x][cel.y] + 1;
                if(step < drag[nx][ny]){
                    drag[nx][ny] = step;
                    q.push(make_pair(nx, ny));
                }
            }
        }
    }
}

int lee[MAXN][MAXN];

bool ok(int cx, int cy, int dist){
    if(cx > 0 && cx <= n && cy > 0 && cy <= m){
        if(harta[cx][cy] != 'D' && harta[cx][cy] != '*'){
            if(drag[cx][cy] >= dist)
                return 1;
            return 0;
        }
        return 0;
    }
    return 0;
}

bool findpath(int dist){
    for(int i = 1; i <= n; ++i){
        for(int j = 1; j <= m; ++j)
            lee[i][j] = 1e9;
    }
    if(drag[sx][sy] >= dist){
        lee[sx][sy] = 0;
        q.push(make_pair(sx, sy));
    }
    while(!q.empty()){
        pair<int, int> cel = q.front();
        q.pop();
        for(int d = 0; d < 4; ++d){
            int nx = cel.x + dx[d], ny = cel.y + dy[d];
            if(ok(nx, ny, dist)){
                int step = lee[cel.x][cel.y] + 1;
                if(step < lee[nx][ny]){
                    lee[nx][ny] = step;
                    q.push(make_pair(nx, ny));
                }
            }
        }
    }
    if(lee[fx][fy] < 1e9)
        return 1;
    return 0;
}

int main()
{
    fin >> n >> m;
    pars();
    expand();
    int rez = 0, pas = 1 << 30;
    while(pas){
        if(findpath(rez + pas))
            rez += pas;
        pas /= 2;
    }
    fout << rez;
    return 0;
}