Cod sursa(job #2328128)

Utilizator iustin948Homoranu Iustin iustin948 Data 25 ianuarie 2019 13:56:05
Problema Barbar Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.89 kb
#include <bits/stdc++.h>
using namespace std;

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

int n, m, startx , starty, k, finx, finy;
pair < int, int > coord[100005];
queue <pair <int, int> > q;
int b[1005][1005];
int a[1005][1005];

void Afisare(int x[1005][1005])
{
    int i,j;
    for(i=1; i<=n; i++)
    {
        for(j=1; j<=m; j++)
            cout << x[i][j] << " ";
        cout << "\n";
    }
}

void Read()
{
    char x;
    fin >> n >> m;
    fin.get();
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
                {
                    fin >> x;
                    if(x == '*') b[i][j] = -1;
                    else if(x == 'D') coord[++k] = {i , j}, b[i][j] = -1;
                    else if(x == 'I') startx = i, starty = j, b[i][j] = 1;
                    else if(x == 'O') finx = i, finy = j, b[i][j] = -1E9;
                }

}

void Refresh()
{
    for(int i = 1; i<=n; i++)
        for(int j =1; j<=m; j++)
            a[i][j] = b[i][j];
}

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};

inline bool Inside(int i, int j)
{
    if(i < 1 || j < 1 || i > n || j > m)
        return 0;
    if(a[i][j] == -1)
        return 0;
    return 1;
}

void Lee()
{
    int i, j, ii ,jj;
    q.push({startx, starty});
    while(!q.empty())
    {
        i = q.front().first;
        j = q.front().second;
        q.pop();
        for(int d = 0; d < 4; d++)
        {
            ii = i + dx[d];
            jj = j + dy[d];
            if(Inside(ii,jj) && (a[ii][jj] == 0 || a[ii][jj] == -1E9) )
            {
                q.push({ii,jj});
                a[ii][jj] = a[i][j] + 1;
            }
        }
    }
}

void Fill(int bin)
{
    int i, j, ii ,jj, lg, cnt = 0;
    for(i=1; i<=k; i++)
    q.push({coord[i].first,coord[i].second});
    lg = q.size();
    while(!q.empty() && cnt < bin )
    {

        lg--;
        i = q.front().first;
        j = q.front().second;
        q.pop();
        for(int d = 0; d < 4; d++)
        {
            ii = i + dx[d];
            jj = j + dy[d];
            if(Inside(ii,jj) && a[ii][jj] == 0)
            {
                q.push({ii,jj});
                a[ii][jj] = -1;
            }
        }
        if(lg == 0)
        {
            cnt++;
            lg = q.size();
        }
    }
}

void Clear()
{
    queue <pair <int, int> > Empty;
    swap(q,Empty);
}

void CautBin()
{
    int mij, st, dr, nr;
    bool p = 0;
    st = 0;
    dr = max(n,m);
    while(st <= dr)
    {
        mij = (st + dr) / 2;
        Refresh();
        Fill(mij);
        Clear();
        Lee();
        if(a[finx][finy] > 0)
            st = mij + 1, p = 1, nr = mij;
        else dr = mij - 1;
    }


    if(p)
    fout << nr+1 << "\n";
    else fout << -1 << "\n";
}

int main()
{
    Read();
    CautBin();
    return 0;
}