Cod sursa(job #2542498)

Utilizator memecoinMeme Coin memecoin Data 10 februarie 2020 07:43:12
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3 kb
#include <fstream>
#include <string>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <math.h>
#include <set>
#include <map>
#include <string.h>
#include <queue>
#include <stack>

#define INF 0x3f3f3f3f

using namespace std;

#ifdef DEBUG
string name = "data";
#else
string name = "barbar";
#endif

ifstream fin(name + ".in");
ofstream fout(name + ".out");

#define MAXN 1024

char a[MAXN][MAXN];
int n, m;

struct Point {
    int x,y;
};

Point startP, endP;

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

int dd[MAXN][MAXN];
bool viz[MAXN][MAXN];

bool canReachEnd(int d) {
    if (d == -1) {
        return false;
    }
    
    memset(viz, 0, sizeof(viz));
    
    queue<Point> q;
    
    if (d > dd[startP.x][startP.y]) {
        return false;
    }
    q.push(startP);
    
    while (!q.empty()) {
        auto node = q.front();
        q.pop();
        
        for (int k = 0; k < 4; ++k) {
            int nx = node.x + dx[k];
            int ny = node.y + dy[k];
            
            if (nx < 0 || nx >= n || ny < 0 || ny >= m) {
                continue;
            }
            
            if (viz[nx][ny]) {
                continue;
            }
            
            if (d > dd[nx][ny]) {
                continue;
            }
            
            if (nx == endP.x && ny == endP.y) {
                return true;
            }
            
            viz[nx][ny] = true;
            q.push({nx, ny});
        }
    }
    
    return false;
}

int find(int low, int high) {
    if (low < 0) {
        return -1;
    }
    if (low > high) {
        return -1;
    }
    
    int mid = (low + high) / 2;

    bool canReach = canReachEnd(mid);
    
    if (!canReach) {
        return find(low, mid - 1);
    }
    
    if (canReach && canReachEnd(mid + 1) == false) {
        return mid;
    }
    
    return find(mid + 1, high);
}

int main() {
    
    fin >> n >> m;
    
    queue<Point> q;
    
    memset(dd, 0x3f, sizeof(dd));
    
    for (int i = 0; i < n; ++i) {
        string s;
        fin >> s;
        for (int j = 0; j < m; ++j) {
            a[i][j] = s[j];
            
            if (s[j] == 'I') {
                startP = {i, j};
            }
            if (s[j] == 'O') {
                endP = {i, j};
            }
            if (s[j] == 'D') {
                q.push({i,j});
                dd[i][j] = 0;
            }
        }
    }
    
    while (!q.empty()) {
        auto node = q.front();
        q.pop();
        
        for (int k = 0; k < 4; ++k) {
            int nx = node.x + dx[k];
            int ny = node.y + dy[k];
            
            if (nx < 0 || nx >= n || ny < 0 || ny >= m) {
                continue;
            }
            
            if (dd[nx][ny] != INF) {
                continue;
            }
            
            if (a[nx][ny] == '*') {
                continue;
            }
            
            dd[nx][ny] = dd[node.x][node.y] + 1;
            q.push({nx, ny});
        }
    }
    
    fout << find(0, max(n, m));
    
    return 0;
}