Cod sursa(job #2032793)

Utilizator netfreeAndrei Muntean netfree Data 5 octombrie 2017 18:11:00
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.65 kb
#include <bits/stdc++.h>
#define pii pair<int,int>

using namespace std;

const int N_MAX = 1000 + 5;

char x[N_MAX][N_MAX];
int dist[N_MAX][N_MAX] ,dp[N_MAX][N_MAX];
int n, m;

int sti, stj, fii, fij;

int Di [] = {0,0,1,-1};
int Dj [] = {1,-1,0,0};

queue<pii> q;

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

bool valid (int i, int j){
    if (i < 1 or j < 1 or i > n or j > m)
        return false;
    return true;
}

void generare_dist(){

    while(!q.empty()){
        int i = q.front().first;
        int j = q.front().second;

        q.pop();

        for(int d = 0; d<4; ++d){
            int ii = i + Di[d];
            int jj = j + Dj[d];

            if(!valid(ii,jj))
                continue;

            if(valid(ii,jj) and x[ii][jj] != '*' and dist[ii][jj] > dist[i][j] + 1){
                dist[ii][jj] =   dist[i][j] + 1;
                q.push({ii,jj});
            }
        }
    }

}

bool pot (int k){
    /// cu dist mai mare sau egala cu k

    for(int i = 1; i<=n; ++i)
        for(int j = 1; j<=n; ++j)
            dp[i][j] = INT_MAX / 2;

    q.push({sti, stj});

    dp[sti][stj] = 0;

     while(!q.empty()){
        int i = q.front().first;
        int j = q.front().second;

        q.pop();

        for(int d = 0; d<4; ++d){
            int ii = i + Di[d];
            int jj = j + Dj[d];

            if(valid(i,j) and x[ii][jj] != '*' and dp[ii][jj] > dp[i][j] + 1 and dist[ii][jj] >= k){
                dp[ii][jj] =   dp[i][j] + 1;
                q.push({ii,jj});
            }
        }
    }

    return (dp[fii][fij] != INT_MAX/2);
}

int solve(){
    int lo = 0, hi = max(n,m)+1;

    while(lo <= hi){
        int mid = (hi + lo) / 2;

        bool qp = pot(mid);

        if(qp and !pot(mid+1))
            return mid;
        if(qp and pot(mid - 1))
            lo = mid + 1;
        else
            hi = mid - 1;
    }

    return -1;
}

int main()
{
    fin >> n >> m;

    for(int i = 1; i<=n; ++i)
        for(int j = 1; j<=m; ++j)
            dist[i][j] = INT_MAX / 2;

    for(int i = 1; i<=n; ++i)
        for (int j = 1; j <= m; j++){
            fin >> x[i][j];
            if(x[i][j] == 'I'){
                sti = i;
                stj = j;
            } else if (x[i][j] == 'O'){
                fii = i;
                fij = j;
            } else if (x[i][j] == 'D'){
                q.push({i,j});
                dist[i][j] = 0;
                //x[i][j] = '*';
            }
        }

    generare_dist();

    if(!pot(0))
        fout << -1;
    else
        fout << solve();

    return 0;
}