Cod sursa(job #2116309)

Utilizator alexge50alexX AleX alexge50 Data 27 ianuarie 2018 14:58:42
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.83 kb
#include <stdio.h>
#include <queue>

enum CellType
{
    AIR = '.',
    WALL = '*',
    DRAGON = 'D',
    START_POINT = 'I',
    GATE = 'O'
};

struct Pos
{
    int m_l, m_c;
    Pos():m_l(0), m_c(0){}
    Pos(int l, int c): m_l(l), m_c(c){}
};

const int MAX_N = 1000;
const int INF = MAX_N * MAX_N;

struct Node
{
    Pos p;
    int costs[4];
    int dist;
} Graph[MAX_N + 2][MAX_N + 2];

char map[MAX_N + 2][MAX_N + 2];
int distmap[MAX_N + 2][MAX_N + 2];
int aux[MAX_N + 2][MAX_N + 2];

int ldir[4] = {0, 0, +1, -1},
    cdir[4] = {+1, -1, 0, 0};

bool checkPath(Pos start, Pos end, int val, int n, int m)
{
    std::queue<Pos> q;

    q.push(start);

    if(distmap[start.m_l][start.m_c] <= val)
        return false;

    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            aux[i][j] = 0;

    aux[start.m_l][start.m_c] = 1;

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

        for(int i = 0; i < 4; i++)
        {
            Pos p2 (p.m_l + ldir[i], p.m_c + cdir[i]);
            if(map[p2.m_l][p2.m_c] != WALL && !aux[p2.m_l][p2.m_c] && distmap[p2.m_l][p2.m_c] > val)
            {
                q.push(p2);
                aux[p2.m_l][p2.m_c] = 1;
            }
        }
    }

    return static_cast<bool>(aux[end.m_l][end.m_c]);
}

int main()
{
    FILE *fin = fopen("barbar.in", "r"),
         *fout = fopen("barbar.out", "w");
    int n, m;
    std::queue<Pos> q;
    Pos start, end;

    fscanf(fin, "%d %d ", &n, &m);

    for(int i = 0; i <= n + 1; i++)
        map[i][0] = map[i][m + 1] = WALL;
    for(int j = 0; j <= m + 1; j++)
        map[0][j] = map[n + 1][j] = WALL;


    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
        {
            fscanf(fin, "%c ", &map[i][j]);
            if(map[i][j] == DRAGON)
            {
                q.push(Pos(i, j));
                distmap[i][j] = 1;
            }
            else if(map[i][j] == START_POINT)
                start = Pos(i, j);
            else if(map[i][j] == GATE)
                end = Pos(i, j);
        }

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

        for(int i = 0; i < 4; i++)
        {
            Pos p2 (p.m_l + ldir[i], p.m_c + cdir[i]);
            if(map[p2.m_l][p2.m_c] != WALL && !distmap[p2.m_l][p2.m_c])
            {
                q.push(p2);
                distmap[p2.m_l][p2.m_c] = 1 + distmap[p.m_l][p.m_c];
            }
        }
    }

    /*for(int i = 1; i < n + 1; i++)
    {
        for(int j = 1; j < m + 1; j++)
            printf("%d ", distmap[i][j]);
        printf("\n");
    }*/

    //cautare binara solutie
    int r = 0, step = 1 << 30;

    while(step)
    {
        if(checkPath(start, end, r + step, n, m))
            r += step;
        step /= 2;
    }

    if(r == 0)
        fprintf(fout, "-1");
    else fprintf(fout, "%d", r);

    fcloseall();
    return 0;
}