Cod sursa(job #2790442)

Utilizator Rares5000Baciu Rares Rares5000 Data 28 octombrie 2021 23:33:49
Problema Barbar Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.15 kb
#include <iostream>
#include <fstream>
#include <queue>
#define oo 2000000000

using namespace std;

ifstream fin("barbar.in");
ofstream fout("barbar.out");

queue< pair<int, int> > q;
queue< pair<int, int> > dragoons;
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
int matmin[1002][1002], n, m, paftenie_x, paftenie_y, iesire_x, iesire_y, nrdragoni;
int matadevarat[1002][1002];
char mat[1002][1002];

void Citire()
{
    int i, j;
    fin >> n >> m;
    for(i = 0; i < n; i++)
        for(j = 0; j < m; j++)
        {
            fin >> mat[i][j];
            if(mat[i][j] == 'I')
            {
                paftenie_x = i;
                paftenie_y = j;
            }
            else if(mat[i][j] == 'O')
            {
                iesire_x = i;
                iesire_y = j;
            }
            else if(mat[i][j] == 'D')
            {
                dragoons.push({i, j});
            }
            else if(mat[i][j] == '*')
                matadevarat[i][j] = 2;
        }
}

inline bool Inside(int x, int y)
{
    return x < n && y < m && x >= 0 && y >= 0;
}

void Lee1()
{
    int x, y, x_urm, y_urm, k, i, j;
    matmin[q.front().first][q.front().second] = 0;
    while(!q.empty())
    {
        x = q.front().first;
        y = q.front().second;
        for(k = 0; k < 4; k++)
        {
            x_urm = x + dx[k];
            y_urm = y + dy[k];
            if(Inside(x_urm, y_urm) && mat[x_urm][y_urm] != '*' && matmin[x_urm][y_urm] > matmin[x][y] + 1)
            {
                matmin[x_urm][y_urm] = matmin[x][y] + 1;
                q.push({x_urm,y_urm});
            }
        }
        q.pop();
    }
}

void Lee2(int mij)
{
    int x, y, x_urm, y_urm, k;
    while(!q.empty())
    {
        x = q.front().first;
        y = q.front().second;
        for(k = 0; k < 4; k++)
        {
            x_urm = x + dx[k];
            y_urm = y + dy[k];
            if(Inside(x_urm, y_urm) && matadevarat[x_urm][y_urm] != 2 && matadevarat[x_urm][y_urm] != 1 && matmin[x_urm][y_urm] >= mij)
            {
                matadevarat[x_urm][y_urm] = 1;
                q.push({x_urm,y_urm});
            }
        }
        q.pop();
    }
}

void ResetMat()
{
    int i, j;
    for(i = 0; i < n; i++)
        for(j = 0; j < m; j++)
            if(matadevarat[i][j] != 2)
                matadevarat[i][j] = 0;
}

int CautBin()
{
    int st, dr, mij, ans = oo;
    st = 1;
    dr = n * m;
    while(st <= dr)
    {
        mij = st + (dr - st) / 2;
        q.push({paftenie_x, paftenie_y});
        Lee2(mij);
        if(matadevarat[iesire_x][iesire_y] == 1)
        {
            ans = mij;
            st = mij + 1;
        }
        else dr = mij - 1;
        ResetMat();
    }
    return ans;
}

void Solve()
{
    int i, j;
    for(i = 0; i < n; i++)
        for(j = 0; j < m; j++)
            matmin[i][j] = oo;

    while(!dragoons.empty())
    {
        q.push({dragoons.front().first, dragoons.front().second});
        Lee1();
        dragoons.pop();
    }
    fout << CautBin();
}


int main()
{
    Citire();
    Solve();
    return 0;
}