Cod sursa(job #1840830)

Utilizator antanaAntonia Boca antana Data 4 ianuarie 2017 21:27:05
Problema Barbar Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.52 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, sumX[MAXN][MAXN], sumY[MAXN][MAXN], startX, startY, stopX, stopY;

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

    int left, right, up, down;

    right = y;
    left = y-dist+1;
    if(left < 1) left = 1;
    if(sumX[x][right] - sumX[x][left-1]) return 0;

    left = y;
    right = y+dist-1;
    if(right > m) right = m;
    if(sumX[x][right] - sumX[x][left-1]) return 0;

    down = x;
    up = x-dist+1;
    if(up < 1) up = 1;
    if(sumY[down][y] - sumY[up-1][y]) return 0;

    down = x+dist-1;
    up = x;
    if(down > n) down = n;
    if(sumY[down][y] - sumY[up-1][y]) return 0;

    return 1;
}

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;
    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, 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') sumX[i][j] = sumY[i][j] = wall[i][j] = 1;
            if(c == 'I') startX = i, startY = j;
            if(c == 'O') stopX = i, stopY = j;
        }
        scanf("%c", &c);
    }

    for(i=1; i<=n; ++i)
        for(j=1; j<=m; ++j)
        {
            sumX[i][j] += sumX[i][j-1];
            sumY[i][j] += sumY[i-1][j];
        }

    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;
}