Cod sursa(job #1743307)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 17 august 2016 22:28:38
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.53 kb
/// O(NM), lazy deletion
#include <bits/stdc++.h>
using namespace std;

const int NMAX = 1005,
           INF = 1e9;

struct PII {
    int x, y;

    inline PII() { }
    inline PII(int _x, int _y) {
        x = _x;
        y = _y;
    }
};

int  n, m;
char mx[NMAX][NMAX];
int  bn[NMAX][NMAX],
      d[NMAX][NMAX];

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

void border_lim(void) {
    for(int i=0; i<=n+1; ++i) {
        mx[i][0]   = '*';
        mx[i][m+1] = '*';
    }
    for(int j=0; j<=m+1; ++j) {
        mx[0][j]   = '*';
        mx[n+1][j] = '*';
    }
}

void dragon_lee(void) {
    queue<PII> q;
    PII now;
    int x, y;

    for(int i=1; i<=n; ++i) {
    for(int j=1; j<=m; ++j) {
        if(mx[i][j]=='D') {
            q.emplace(i, j);
            d[i][j] = 1;
        }
    }}

    while(!q.empty()) {
        now = q.front();
        q.pop();

        for(int i=0; i<4; ++i) {
            x = now.x + dx[i];
            y = now.y + dy[i];

            if(mx[x][y]!='*' && d[x][y]==0) {
                d[x][y] = d[now.x][now.y] + 1;
                q.emplace(x, y);
            }
        }
    }
}

void lazy_deletion(int &ant) {
    deque<PII> dq;
    PII now, beg, dest;
    int x, y;

    ant = INF;

    for(int i=1; i<=n; ++i)
    for(int j=1; j<=m; ++j)
        if(mx[i][j]=='I')
            dq.push_front(PII(i, j)),
            beg = PII(i, j);

    for(int i=1; i<=n; ++i)
    for(int j=1; j<=m; ++j)
        if(mx[i][j]=='O')
            dest = PII(i, j);

    bn[beg.x][beg.y] = true;

    while(!dq.empty()) {
        now = dq.front();
        dq.pop_front();

        ant = min(ant, d[now.x][now.y]);

        if(mx[now.x][now.y]=='O')
            break;

        for(int i=0; i<4; ++i) {
            x = now.x + dx[i];
            y = now.y + dy[i];

            if(mx[x][y]!='*' && !bn[x][y]) {
                if(ant <= d[x][y])
                    dq.push_front(PII(x, y));
                else
                    dq.push_back(PII(x, y));
                bn[x][y] = true;
            }
        }
    }

    --ant;

    if(now.x!=dest.x || now.y!=dest.y)
        ant = -1;
}

int main(void) {
    freopen("barbar.in",  "r", stdin);
    freopen("barbar.out", "w", stdout);
    int ant;

    scanf("%d%d ",&n,&m);
    for(int i=1; i<=n; ++i)
        gets(mx[i] + 1);

    border_lim();
    dragon_lee();
    lazy_deletion(ant);

    printf("%d\n",ant);

    fclose(stdin);
    fclose(stdout);
    return 0;
}