Cod sursa(job #2073816)

Utilizator MaligMamaliga cu smantana Malig Data 23 noiembrie 2017 19:08:04
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.68 kb
#include <iostream>
#include <fstream>
#include <queue>

#if 1
#define pv(x) cout<<#x<<" = "<<x<<"; ";cout.flush()
#define pn cout<<endl
#else
#define pv(x)
#define pn
#endif

using namespace std;
ifstream in("barbar.in");
ofstream out("barbar.out");

#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
const int NMax = 1e3 + 5;

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

int N,M;
char a[NMax][NMax];
bool vis[NMax][NMax];
int distDragon[NMax][NMax];

struct queueElement {
    int x,y,pasi;
    queueElement(int _x = 0,int _y = 0,int _pasi = 0): x(_x), y(_y), pasi(_pasi) {}
};

bool canEscape(int,int,int,int,int);

int main() {
    in>>N>>M;

    int xStart = 0,yStart = 0,xEnd = 0,yEnd = 0;
    queue< queueElement > Q;
    for (int i=1;i <= N;++i) {
        in>>(a[i]+1);

        for (int j=1;j <= M;++j) {
            if (a[i][j] == 'D') {
                Q.push( queueElement(i,j,0) );
                distDragon[i][j] = 0;
                vis[i][j] = true;
            }
            else if (a[i][j] == 'I') {
                xStart = i;
                yStart = j;
            }
            else if (a[i][j] == 'O') {
                xEnd = i;
                yEnd = j;
            }
        }
    }

    /*
    for (int i=1;i <= N;++i) {
        for (int j=1;j <= M;++j) {
            cout<<a[i][j]<<' ';
        }
        cout<<'\n';
    }
    cout<<'\n';
    //*/

    int maxDist = 0;
    while (Q.size()) {
        queueElement e = Q.front();
        Q.pop();

        //pv(e.x);pv(e.y);pv(e.pasi);pn;

        for (int k=0;k < 4;++k) {
            int nx = e.x + dx[k],
                ny = e.y + dy[k];

            if (nx < 1 || nx > N || ny < 1 || ny > M || a[nx][ny] == '*' || vis[nx][ny]) {
                continue;
            }

            distDragon[nx][ny] = e.pasi + 1;
            vis[nx][ny] = true;
            Q.push( queueElement(nx,ny,e.pasi + 1) );

            maxDist = max(maxDist,distDragon[nx][ny]);
        }
    }

    /*
    for (int i=1;i <= N;++i) {
        for (int j=1;j <= M;++j) {
            cout<<distDragon[i][j]<<' ';
        }
        cout<<'\n';
    }
    cout<<'\n';
    //*/

    int pw = 1, ans = 0;
    for (;pw <= maxDist;pw <<= 1) ;
    pw >>= 1;

    while (pw) {
        if ( canEscape(xStart,yStart,xEnd,yEnd, ans + pw) ) {
            ans += pw;
        }

        pw >>= 1;
    }

    if (ans == 0 && canEscape(xStart,yStart,xEnd,yEnd,0) == false) {
        out<<"-1\n";
    }
    else {
        out<<ans<<'\n';
    }

    return 0;
}

bool canEscape(int xStart,int yStart,int xEnd,int yEnd,int minDist) {

    for (int i=1;i <= N;++i) {
        for (int j=1;j <= M;++j) {
            vis[i][j] = false;
        }
    }

    queue< pair<int,int> > Q;

    Q.push( mp(xStart,yStart) );
    while (Q.size()) {
        pair<int,int> p = Q.front();
        Q.pop();

        if (p.first == xEnd && p.second == yEnd) {
            return true;
        }

        for (int k=0;k < 4;++k) {
            int nx = p.first + dx[k],
                ny = p.second + dy[k];

            if (vis[nx][ny] || distDragon[nx][ny] < minDist) {
                continue;
            }

            if (nx < 1 || nx > N || ny < 1 || ny > M || a[nx][ny] == '*') {
                continue;
            }

            vis[nx][ny] = true;
            Q.push( mp(nx,ny) );
        }
    }

    /*
    cout<<minDist<<'\n';
    for (int i=1;i <= N;++i) {
        for (int j=1;j <= M;++j) {
            cout<<vis[i][j]<<' ';
        }
        cout<<'\n';
    }
    cout<<'\n';
    //*/

    return false;
}