Cod sursa(job #3138790)

Utilizator SarakottoBogudanSaracut Bogdan Andrei SarakottoBogudan Data 22 iunie 2023 13:15:20
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.76 kb
#include <fstream>
#include <string>
#include <queue>

using namespace std;

ifstream cin("barbar.in");
ofstream cout("barbar.out");

struct coord{
    int lin, col;
};

coord start;
coord fin;
coord dragon;

queue < coord > q;

int matDragon[1001][1001], matIn[1001][1001], n, m;

int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

bool inmat(coord cur)
{
    return cur.lin >= 1 && cur.lin <= n && cur.col >= 1 && cur.col <= m;
}

bool lee(int mat[][1001], coord fin, int dist)
{
    while(!q.empty())
    {
        coord cur = q.front();
        q.pop();
        coord vecin;
        for(int d = 0; d < 4; d++)
        {
            vecin.lin = cur.lin + dir[d][0];
            vecin.col = cur.col + dir[d][1];
            if(inmat(vecin) && matDragon[vecin.lin][vecin.col] >= dist && mat[vecin.lin][vecin.col] == 0)
            {
                mat[vecin.lin][vecin.col] = mat[cur.lin][cur.col] + 1;
                q.push(vecin);
            }
        }
    }
    return mat[fin.lin][fin.col] > 0;
}

void initial(coord st)
{
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            matIn[i][j] = 0;
        }
    }
    matIn[st.lin][st.col] = 1;
    q.push(st);
}

int caut_binar(int stg, int dr)
{
    int ans = 0;
    while(stg <= dr)
    {
        int mij = (stg + dr) / 2;
        initial(start);
        if(lee(matIn, fin, mij))
        {
            stg = mij + 1;
            ans = mij;
        }
        else 
        {
            dr = mij - 1;
        }

    }
    return ans;
}

int main()
{
    cin >> n >> m;
    string s;
    getline(cin, s);
    for(int i = 1; i <= n; i++)
    {
        getline(cin, s);
        for(int j = 0; j < m; j++)
        {
            if(s[j] == '*')
            {
                matDragon[i][j + 1] = -1;
                matIn[i][j + 1] = -1;
            }
            if(s[j] == 'D')
            {
                matDragon[i][j + 1] = 1;
                dragon.lin = i;
                dragon.col = j + 1;
                q.push(dragon);
            }
            if(s[j] == 'I')
            {
                start.lin = i;
                start.col = j + 1;
            }
            if(s[j] == 'O')
            {
                fin.lin = i;
                fin.col = j + 1;
            }
        }
    }

    int dist_min = 1e7;

    lee(matDragon, fin, 0);
    initial(start);

    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            if(i == start.lin && j == start.col && matDragon[i][j] < dist_min)
            {
                dist_min = matDragon[i][j];
            }
        }
    }

    cout << caut_binar(1, dist_min) - 1 << '\n';

    return 0;
}