Cod sursa(job #3141777)

Utilizator Chris_BlackBlaga Cristian Chris_Black Data 16 iulie 2023 15:10:39
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.39 kb
#include <bits/stdc++.h>
#define PI pair<int, int>
#define F first
#define S second
using namespace std;
const int N = 1009, dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1}, Inf = 0x3f3f3f3f;

int r, c, n, m, a, b, x, y, mat[N][N], dist[N][N], traseu[N][N];

char line[N];
vector<PI> dragoni;
PI start, stop;

inline bool inmat(int x, int y){return x >= 1 && x <= r && y >= 1 && y <= c;}
void Get_Dist()
{
    queue<PI> q;
    for(auto i : dragoni)
    {
        dist[i.F][i.S] = 0;
        q.push(i);
    }

    while(!q.empty())
    {
        int x = q.front().F,
        y = q.front().S;
        q.pop();

        for(int k = 0; k < 4; ++k)
        {
            int nx = x + dx[k], ny = y + dy[k];
            if(inmat(nx, ny) && dist[nx][ny] == Inf)
            {
                dist[nx][ny] = dist[x][y] + 1;
                q.push({nx, ny});
            }
        }
    }
}


bool Exista_Drum(int dmin)
{
    if(dist[start.F][start.S] < dmin)return false;

    memset(traseu, 0, sizeof(traseu));
    queue<PI> q;
    q.push(start);
    traseu[start.F][start.S] = 1;

    while(!q.empty())
    {
        int x = q.front().F, y = q.front().S;
        q.pop();

        for(int k = 0; k < 4; ++k)
        {
            int nx = x + dx[k], ny = y + dy[k];

            if(inmat(nx, ny) && !traseu[nx][ny] && !mat[nx][ny] && dist[nx][ny] >= dmin)
            {
                traseu[nx][ny] = 1;
                q.push({nx, ny});
            }
        }
    }

    return (traseu[stop.F][stop.S] == 1);
}

int main()
{
    freopen("barbar.in", "r", stdin);
    freopen("barbar.out", "w", stdout);

    cin >> r >> c;
    cin.get();
    for(int i = 1; i <= r; ++i)
    {
        cin.get(line, N);
        cin.get();

        for(int j = 1; j <= c; ++j)
        {
            if(line[j - 1] == '*')mat[i][j] = 1;
            else if(line[j - 1] == 'D')dragoni.push_back({i, j});
            else if(line[j - 1] == 'I')start = {i, j};
            else if(line[j - 1] == 'O')stop = {i, j};
        }
    }

    memset(dist, Inf, sizeof(dist));
    Get_Dist();

    int st = 0, dr = r + c - 1, mij, poz = - 1;
    while(st <= dr)
    {
        mij = (st + dr) >> 1;
        if(Exista_Drum(mij))
        {
            st = mij + 1;
            poz = mij;
        }
        else
            dr = mij - 1;
    }

    cout << poz;
    return 0;
}