Cod sursa(job #605528)

Utilizator dacyanMujdar Dacian dacyan Data 30 iulie 2011 15:37:23
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.74 kb
#include <fstream>
#include <vector>
#include <string>
#include <queue>
#define DIM 1001
#define INF 0x3f3f3f3f
using namespace std;

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

int n, m, sol(-1);
int a[DIM][DIM], d[DIM][DIM];
int ip, jp, is, js;
vector<pair<int,int> > drag;
queue<pair<int,int> > Q;

const int di[] = {-1, 0, 1, 0};
const int dj[] = {0, 1, 0, -1};

bool BF(int d);
bool OK(int i, int j);

int main()
{
    fin >> m >> n;
    string s;
    for (int i = 1; i <= m; ++i)
    {
        fin >> s;
        for (int j = 0; j < n; ++j)
        {
            d[i][j+1] = INF;
            if (s[j] == '*') a[i][j+1] = 1;
            if (s[j] == 'D') drag.push_back(make_pair(i, j+1));
            if (s[j] == 'I')
            {
                ip = i;
                jp = j + 1;
            }
            if (s[j] == 'O')
            {
                is = i;
                js = j + 1;
            }
        }
    }
    fin.close();
    
    for (int i = 0; i < drag.size(); ++i)
    {
        Q.push(make_pair(drag[i].first, drag[i].second));
        d[drag[i].first][drag[i].second] = 0;
    }                      
    while (!Q.empty())
    {
        int i = Q.front().first;
        int j = Q.front().second;
        Q.pop();
        for (int k = 0; k < 4; ++k)
        {
            int iv = i + di[k];
            int jv = j + dj[k];
            if (OK(iv, jv) && d[iv][jv] > d[i][j] + 1)
            {
                d[iv][jv] = d[i][j] + 1;
                Q.push(make_pair(iv,jv));
            }
        }
    }
    
    int st(0), dr(d[ip][jp]);
    while (st <= dr)
    {
        int mij = (st + dr) / 2;
        if (BF(mij)) 
        {
            sol = mij;
            st = mij + 1;
        }
        else dr = mij - 1;
    }
    
    ofstream fout("barbar.out");
    fout << sol << '\n';
    fout.close();
    return 0;
}

bool OK(int i, int j)
{
    return i >= 1 && j >= 1 && i <= m && j <= n && !a[i][j];
}

bool BF(int D)
{
   while (!Q.empty()) Q.pop();
   Q.push(make_pair(ip, jp));
   
   vector<bool> s[DIM];
   for (int i = 1; i <= m; ++i)
      s[i].resize(n+1);
      
   s[ip][jp] = 1;
   while (!Q.empty())
   {
       pair<int, int> x = Q.front();
       int i = x.first;
       int j = x.second;
       Q.pop();
       for (int k = 0; k < 4; ++k)
       {
            int iv = i + di[k];
            int jv = j + dj[k];
            if (OK(iv, jv) && !s[iv][jv] && d[iv][jv] >= D)
            {
                Q.push(make_pair(iv,jv));
                s[iv][jv] = 1;
                if (iv == is && jv == js) return true;
            }
        }
    }
    return false;
}