Cod sursa(job #690778)

Utilizator repp4raduRadu-Andrei Szasz repp4radu Data 25 februarie 2012 21:05:05
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.9 kb
#include <cstdio>
#include <cstring>
#include <algorithm>

#define MAX 1050

using namespace std;

char matrice[MAX][MAX];
bool visit[MAX][MAX];
long long dist[MAX][MAX], b, sol = -1;
int r, c;
int depl_x[] = {-1, 0, 1, 0};
int depl_y[] = {0, 1, 0, -1};

struct point
{
    int x, y;

    bool operator==(point a)
    {
        return this->x == a.x && this->y == a.y;
    }
} coada[MAX * MAX], start, stop;

void citire()
{
    freopen("barbar.in", "r", stdin);
    scanf("%d %d\n", &r, &c);
    int i;
    for(i = 0; i < r; i++)
        gets(matrice[i]);
}

void prepare()
{
    int i, j;
    for(i = 0; i < r; i++)
    {
        for(j = 0; j < c; j++)
        {
            if(matrice[i][j] == 'D')
            {
                coada[++b].x = i;
                coada[b].y = j;
                dist[coada[b].x][coada[b].y] = 0;
                visit[coada[b].x][coada[b].y] = true;
            }
            else
            {
                if(matrice[i][j] == 'I')
                {
                    start.x = i;
                    start.y = j;
                }
                else if(matrice[i][j] == 'O')
                {
                    stop.x = i;
                    stop.y = j;
                }
                dist[i][j] = MAX * MAX;
            }
        }
    }
}

void genDist()
{
    int a = 1, i;
    while(a <= b)
    {
        for(i = 0; i < 4; i++)
        {
            if(coada[a].x + depl_x[i] >= 0 && coada[a].x + depl_x[i] < r &&
               coada[a].y + depl_y[i] >= 0 && coada[a].y + depl_y[i] < c &&
               matrice[coada[a].x + depl_x[i]][coada[a].y + depl_y[i]] != '*')
               {
                   if(!visit[coada[a].x + depl_x[i]][coada[a].y + depl_y[i]])
                   {
                       coada[++b].x = coada[a].x + depl_x[i];
                       coada[b].y = coada[a].y + depl_y[i];
                       dist[coada[b].x][coada[b].y] = dist[coada[a].x][coada[a].y] + 1;
                       visit[coada[a].x + depl_x[i]][coada[a].y + depl_y[i]] = true;
                   }
                   else if(dist[coada[a].x + depl_x[i]][coada[a].y + depl_y[i]] > dist[coada[a].x][coada[a].y] + 1)
                   {
                       dist[coada[a].x + depl_x[i]][coada[a].y + depl_y[i]] = dist[coada[a].x][coada[a].y] + 1;
                   }
               }
        }
        a++;
    }
}

bool lee(long long minim)
{
    long long a = 1, i;
    b = 1;
    while(a <= b)
    {
        for(i = 0; i < 4; i++)
        {
            if(coada[a].x + depl_x[i] >= 0 && coada[a].x + depl_x[i] < r &&
                    coada[a].y + depl_y[i] >= 0 && coada[a].y + depl_y[i] < c &&
                    !visit[coada[a].x + depl_x[i]][coada[a].y + depl_y[i]] &&
                    matrice[coada[a].x + depl_x[i]][coada[a].y + depl_y[i]] != '*' &&
                    dist[coada[a].x + depl_x[i]][coada[a].y + depl_y[i]] >= minim)
        {
            coada[++b].x = coada[a].x + depl_x[i];
                coada[b].y = coada[a].y + depl_y[i];
                visit[coada[b].x][coada[b].y] = true;
                if(coada[b] == stop)
                    return true;
            }
        }
        a++;
    }
    return false;
}

void caut()
{
    long long begin = 0, end = dist[start.x][start.y], mid = (begin + end) >> 1;
    while(begin <= end)
    {
        memset(visit, 0, MAX * MAX * sizeof(bool));
        memset(coada, 0, MAX * MAX * sizeof(point));
        if(lee(mid))
        {
            sol = mid;
            begin = mid + 1;
        }
        else
        {
            end = mid - 1;
        }
        mid = (begin + end) >> 1;
    }
}

void afisare()
{
    freopen("barbar.out", "w", stdout);
    printf("%lld", sol);
    fclose(stdout);
}

int main()
{
    citire();
    prepare();
    genDist();
    caut();
    afisare();
    return 0;
}