Cod sursa(job #2033566)

Utilizator TherevengerkingSurani Adrian Therevengerking Data 6 octombrie 2017 23:58:18
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.41 kb
#include <bits/stdc++.h>

using namespace std;
#define pii pair<int,int>
#define x first
#define y second
ifstream fin("barbar.in");
ofstream fout("barbar.out");
const int Di[] = {-1, 0 , 1 , 0};
const int Dj[] = {0, -1, 0 , 1};
const int Nmax = 1000 + 5;
int dp[Nmax][Nmax];
char b[Nmax][Nmax];
bool viz[Nmax][Nmax];
queue<pii>q;
string s;
int n, m, si, sj, fi, fj, lo ,hi;
bool ok(int i , int j)
{
    return i >= 1 && j >= 1 && i <= n && j <= m;
}
bool f(int nr)
{
    if(dp[si][sj] < nr)return 0;
    q.push({si, sj});
    viz[si][sj] = 1;
    while(!q.empty())
    {
        int i = q.front().x;
        int j = q.front().y;
        q.pop();
        for(int d = 0; d < 4; ++ d)
        {
            int ii = i + Di[d];
            int jj = j + Dj[d];
            if(ok(ii,jj) && !viz[ii][jj] && dp[ii][jj] >= nr)
            {
                viz[ii][jj] = 1;
                q.push({ii,jj});
            }
        }
    }
    return viz[fi][fj];
}
int main()
{
    fin >> n >> m;
    for(int i = 1; i <= n; ++i)
    {
        fin >> s;
        for(int j = 0; j < s.size(); ++j)
            b[i][j + 1] = s[j];
    }
    for(int i = 1; i <= n; ++i)
        for(int j =1; j <= m; ++j)
        {
            dp[i][j] = 1 << 30;
            if(b[i][j] == '*')dp[i][j] = -1;
            else if(b[i][j] == 'D')dp[i][j] = 0, q.push({i,j});
            else if (b[i][j] == 'I')si =i, sj = j;
            else if(b[i][j] == 'O')fi = i, fj = j;
        }
    int maxim = 0;
    while(!q.empty())
    {
        int i = q.front().x;
        int j = q.front().y;
        q.pop();
        if(dp[i][j] > maxim) maxim = dp[i][j];
        for(int d = 0; d < 4; ++ d)
        {
            int ii = i + Di[d];
            int jj = j + Dj[d];
            if(ok(ii,jj) && dp[ii][jj] > dp[i][j] + 1 && dp[ii][jj]!= -1)
            {
                dp[ii][jj] = dp[i][j] + 1;
                q.push({ii,jj});
            }
        }
    }
    if(dp[fi][fj] == 1 << 30 )
    {
        cout << -1;
        exit(0);
    }
    lo = 0; hi = max(n, m) + 1;
    while(hi - lo > 1)
    {
        int mid = lo + (hi - lo) / 2;
        if(f(mid))lo = mid;
        else hi = mid;
        for(int i  =1 ; i <= n; ++i)
            for(int j = 1; j <= m; ++j)
                viz[i][j] = 0;
    }
    if((lo == maxim && !f(maxim)) || lo == 0)fout << -1;
    else fout << lo;
    return 0;
}