Cod sursa(job #2790501)

Utilizator Rares5000Baciu Rares Rares5000 Data 29 octombrie 2021 10:14:47
Problema Barbar Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.4 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 vis[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});
            }
        }
}

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 DFS(int x, int y, int mij, int &check)
{
    if(x == iesire_x && y == iesire_y)
    {
        check = 1;
        return;
    }
    vis[x][y] = 1;
    for(int i = 0; i < 4 && check == 0; i++)
    {
        int x_urm, y_urm;
        x_urm = x + dx[i];
        y_urm = y + dy[i];
        if(Inside(x_urm, y_urm) && mat[x_urm][y_urm] != '*' && vis[x_urm][y_urm] != 1 && matmin[x_urm][y_urm] >= mij)
        {
            DFS(x_urm, y_urm, mij, check);
        }
    }
    vis[x][y] = 0;
}

int CautBin()
{
    int st, dr, mij, ans = oo, check;
    st = 1;
    dr = n * m;
    while(st <= dr)
    {
        check = 0;
        mij = st + (dr - st) / 2;
        DFS(paftenie_x, paftenie_y, mij, check);
        if(check == 1)
        {
            ans = mij;
            st = mij + 1;
        }
        else dr = mij - 1;
    }
    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;
}