Cod sursa(job #2296072)

Utilizator cahemanCasian Patrascanu caheman Data 4 decembrie 2018 11:57:44
Problema Barbar Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.06 kb
#include<cstdio>
#include<queue>
#include<cstring>

using namespace std;

char mat[1005][1005], viz[1002005];
int dist[1002005];
queue <int> q[90005], dragonasi, qc;

int main()
{
    freopen("barbar.in", "r", stdin);
    freopen("barbar.out", "w", stdout);
    int r, col, i, j, start, finish, curent, constr;
    scanf("%d%d\n", &r, &col);
    constr = r + 1;
    if(col >= constr)
        constr = col + 1;
    for(i = 1; i <= r; ++ i)
        scanf("%s", &mat[i]);
    for(i = 1; i <= r; ++ i)
        for(j = 1; j <= col; ++ j)
        {
            if(mat[i][j] == 'D')
            {
                dragonasi.push(i * constr + j);
                viz[i * constr + j] = 1;
            }
            if(mat[i][j] == 'I')
                start = i * constr + j;
            if(mat[i][j] == 'O')
                finish = i * constr + j;
        }
    for(i = 0; i <= r + 1; ++ i)
        mat[i][0] = mat[i][col + 1] = '*';
    for(i = 0; i <= col + 1; ++ i)
        mat[0][i] = mat[r + 1][i] = '*';
    while(!(dragonasi.empty()))
    {
        curent = dragonasi.front();
        if(viz[curent + constr] == 0 && mat[curent / constr + 1][curent % constr] != '*')
        {
            dist[curent + constr] = dist[curent] + 1;
            dragonasi.push(curent + constr);
            viz[curent + constr] = 1;
        }
        if(viz[curent - constr] == 0 && mat[curent / constr - 1][curent % constr] != '*')
        {
            dist[curent - constr] = dist[curent] + 1;
            dragonasi.push(curent - constr);
            viz[curent - constr] = 1;
        }
        if(viz[curent + 1] == 0 && mat[curent / constr][curent % constr + 1] != '*')
        {
            dist[curent + 1] = dist[curent] + 1;
            dragonasi.push(curent + 1);
            viz[curent + 1] = 1;
        }
        if(viz[curent - 1] == 0 && mat[curent / constr][curent % constr - 1] != '*')
        {
            dist[curent - 1] = dist[curent] + 1;
            dragonasi.push(curent - 1);
            viz[curent - 1] = 1;
        }
        dragonasi.pop();
    }
    if(viz[finish] == 0)
    {
        printf("-1");
        return 0;
    }
    for(i = 1; i <= 1002 * 1000; ++ i)
        viz[i] = 0;
    i = dist[start];
    q[i].push(start);
    while(viz[finish] == 0 && i >= 1)
    {
        while(!q[i].empty())
        {
            curent = q[i].front();
            viz[curent] = 1;
            q[i].pop();
            qc.push(curent);
        }
        while(!qc.empty())
        {
            curent  = qc.front();
            if(viz[curent + constr] == 0 && mat[curent / constr + 1][curent % constr] != '*')
            {
                if(dist[curent + constr] >= i)
                    qc.push(curent + constr);
                else
                    q[dist[curent + constr]].push(curent + constr);
                viz[curent + constr] = 1;
            }
            if(viz[curent - constr] == 0 && mat[curent / constr - 1][curent % constr] != '*')
            {
                if(dist[curent - constr] >= i)
                    qc.push(curent - constr);
                else
                    q[dist[curent - constr]].push(curent - constr);
                viz[curent - constr] = 1;
            }
            if(viz[curent + 1] == 0 && mat[curent / constr][curent % constr + 1] != '*')
            {
                if(dist[curent + 1] >= i)
                    qc.push(curent + 1);
                else
                    q[dist[curent + 1]].push(curent + 1);
                viz[curent + 1] = 1;
            }
            if(viz[curent - 1] == 0 && mat[curent / constr][curent % constr - 1] != '*')
            {
                if(dist[curent - 1] >= i)
                    qc.push(curent - 1);
                else
                    q[dist[curent - 1]].push(curent - 1);
                viz[curent - 1] = 1;
            }
            qc.pop();
        }
        -- i;
    }
    ++ i;
    if(viz[finish] == 0)
        i = 0;
    if(i > dist[finish])
        i = dist[finish];
    printf("%d", i);
    return 0;
}