Cod sursa(job #1816965)

Utilizator Coroian_DavidCoroian David Coroian_David Data 27 noiembrie 2016 10:54:51
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.58 kb
#include <cstdio>

using namespace std;

FILE *f, *g;

const int dl[] = {0, -1, 0, 1, 0};
const int dc[] = {0, 0, 1, 0, -1};

int distDrag[1005][1005];

int a[1005][1005];

bool dragons[1005][1005];

struct pozxy
{
    int x, y;
};

pozxy start, en, poz, next;

pozxy dragon[1000009];

int dragDr, dragSt = 1;

int st, dr;

int n, m;

int minDragon = -1;

void readFile()
{
    int i, j;
    char cr;

    f = fopen("barbar.in", "r");

    fscanf(f, "%d%d\n", &n, &m);

    for(i = 1; i <= n; i ++)
    {
        for(j = 1; j <= m; j ++)
        {
            fscanf(f, "%c", &cr);



            if(cr == 'I')
            {
                start.x = i;
                start.y = j;
            }

            if(cr == 'O')
            {
                en.x = i;
                en.y = j;
            }

            if(cr == 'D')
            {
                dragon[++ dragDr].x = i;
                dragon[dragDr].y = j;

                dragons[i][j] = 1;
            }

            if(cr == '*')
            {
                a[i][j] = -1;
                distDrag[i][j] = -1;
            }
        }



        fscanf(f, "%c", &cr);
    }

    fclose(f);
}

void emptyCave()
{
    int i, j;

    for(i = 1; i <= n; i ++)
    {
        for(j = 1; j <= m; j ++)
            a[i][j] = 0;
    }
}

void wallTheCave()
{
    int i;

    for(i = 0; i <= n + 1; i ++)
        distDrag[i][0] = distDrag[i][m + 1] = a[i][0] = a[i][m + 1] = -1;

    for(i = 0; i <= m + 1; i ++)
        distDrag[0][i] = distDrag[n + 1][i] = a[0][i] = a[n + 1][i] = -1;
}

void takeOutTheDragons()
{
    int i;

    while(dragSt <= dragDr)
    {
        poz = dragon[dragSt ++];

        for(i = 1; i <= 4; i ++)
        {
            next.x = poz.x + dl[i];
            next.y = poz.y + dc[i];

            if((distDrag[next.x][next.y] == 0 && dragons[next.x][next.y] == 0) || distDrag[next.x][next.y] > distDrag[poz.x][poz.y] + 1)
            {
                dragon[++ dragDr] = next;

                distDrag[next.x][next.y] = distDrag[poz.x][poz.y] + 1;
            }
        }
    }
}

bool minDist(int n)
{
    if(n > distDrag[start.x][start.y])
        return false;

    if(n > distDrag[en.x][en.y])
        return false;

    emptyCave();

    int i;

    st = dr = 1;

    dragon[1] = start;

    while(st <= dr)
    {
        poz = dragon[st ++];

        for(i = 1; i <= 4; i ++)
        {
            next.x = poz.x + dl[i];
            next.y = poz.y + dc[i];


            if(distDrag[next.x][next.y] >= n && (a[next.x][next.y] > a[poz.x][poz.y] + 1 || a[next.x][next.y] == 0))
            {
                if(next.x == en.x && next.y == en.y)
                    return true;

                dragon[++ dr] = next;

                a[next.x][next.y] = distDrag[poz.x][poz.y] + 1;
            }
        }
    }

    return false;
}

void cautBin()
{
    int i = 0;
    int pas = 1 << 20;

    while(pas != 0)
    {
        if(minDist(i + pas) != 0)
        {
            i += pas;

            if(i + pas > minDragon)
                minDragon = i;
        }

        pas /= 2;
    }
}

void solve()
{
    wallTheCave();

    takeOutTheDragons();

    cautBin();
}

void printFile()
{
    g = fopen("barbar.out", "w");


    if(minDragon == -1)
    {
        if(minDist(0) != 0)
            minDragon = 0;
    }

    fprintf(g, "%d\n", minDragon);

    fclose(g);
}


int main()
{
    readFile();

    solve();

    printFile();

    return 0;
}