Cod sursa(job #1954133)

Utilizator dragos231456Neghina Dragos dragos231456 Data 5 aprilie 2017 10:54:58
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.66 kb
#include <cstdio>
#include <queue>
#include <cstring>

#define MAXN 1001

using namespace std;

queue < pair<int, int> > q;

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

bool wall[MAXN][MAXN], seen[MAXN][MAXN];
int n, m, dragonDistance[MAXN][MAXN], startX, startY, stopX, stopY;

inline bool ok(int x, int y)
{
    if(x < 1 || x > n || y < 1 || y > m) return 0;
    if(seen[x][y] || wall[x][y]) return 0;

    return 1;
}

void dragonBFS()
{
    int nextRow, nextCol, row, col, i;

    while(!q.empty())
    {
        row = q.front().first;
        col = q.front().second;
        q.pop();

        for(i=0; i<4; ++i)
        {
            nextRow = row + dx[i];
            nextCol = col + dy[i];
            if(ok(nextRow, nextCol))
            {
                dragonDistance[nextRow][nextCol] = dragonDistance[row][col] + 1;
                seen[nextRow][nextCol] = 1;
                q.push(make_pair(nextRow, nextCol));
            }
        }
    }
}

bool bfs(int dist)
{
    int nextRow, nextCol, i, row, col;

    while(!q.empty()) q.pop();

    memset(seen, 0, sizeof(seen));

    q.push(make_pair(startX, startY));

    seen[startX][startY] = 1;
    if(dragonDistance[startX][startY] < dist)
        return 0;

    while(!q.empty())
    {
        row = q.front().first;
        col = q.front().second;

        q.pop();
        for(i=0; i<4; ++i)
        {
            nextRow = row + dx[i];
            nextCol = col + dy[i];

            if(ok(nextRow, nextCol) && dragonDistance[nextRow][nextCol] >= dist)
            {
                seen[nextRow][nextCol] = 1;
                q.push(make_pair(nextRow, nextCol));

                if(nextRow == stopX && nextCol == stopY)
                    return 1;
            }
        }
    }

    return seen[stopX][stopY];
}

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

    int i, j, pas = 1, ans = 0;
    char c;

    scanf("%d%d\n", &n, &m);

    for(i=1; i<=n; ++i)
    {
        for(j=1; j<=m; ++j)
        {
            scanf("%c", &c);
            if(c == '*') wall[i][j] = 1;
            if(c == 'D') wall[i][j] = seen[i][j] = 1, q.push(make_pair(i, j));
            if(c == 'I') startX = i, startY = j;
            if(c == 'O') stopX = i, stopY = j;
        }
        scanf("%c", &c);
    }

    dragonBFS();

    while((pas<<1) <= n && (pas<<1) <= m) pas<<=1;

    for(; pas>=1; pas>>=1)
        if(ans+pas<=n && ans+pas<=m && bfs(ans+pas))
            ans += pas;

    if(ans == 0){
        printf("-1");
        return 0;
    }

    printf("%d", ans);

    return 0;
}