Cod sursa(job #289512)

Utilizator silvia_the_bestSilvia Pripoae silvia_the_best Data 26 martie 2009 19:37:30
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.24 kb
#include <cstdio>
#include <algorithm>
#include <queue>
#define FIN "barbar.in"
#define FOUT "barbar.out"
#define N 1010
#define INF 1000000
using namespace std;

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

int r,c, dist[N][N], d[N][N], answer;
queue <pair <int,int> > q;
pair <int,int> b,e;

void read()
{
    char s[N];
    freopen(FIN, "r", stdin);
    scanf("%d %d\n", &r, &c);

    for (int i = 1; i <= r; ++i)
    {
        gets(s);

        for (int j = 0; s[j]; ++j)
        {
            //if (s[j] == '.')
                //d[i][j] = -1;
            d[i][j + 1] = dist[i][j + 1] = INF;
            if (s[j] == '*')
                d[i][j + 1] = -2;
            if (s[j] == 'D')
            {
                dist[i][j + 1] = 0;
                q.push( make_pair(i, j + 1) );
            }
            if (s[j] == 'I')
            {
                b = make_pair(i, j+ 1);
                d[i][j + 1] = 0;
            }
            if (s[j] == '0')
                e = make_pair(i, j + 1);
            if (s[j] == 'O')
                e = make_pair(i, j + 1);
        }
    }
}

void BFS(int V[][N])
{
    pair <int, int> p1,p2;
    for (int  i = 0; i <= r; ++i)
        V[i][0] = V[i][c + 1] = -2;
    for (int i = 0; i <= c; ++i)
        V[0][i] = V[r + 1][i] = -2;
    while (!q.empty())
    {
        p1 = q.front();
        q.pop();
        for (int i = 0; i < 4; ++i)
        {
            p2 = make_pair(p1.first + dx[i], p1.second + dy[i]);
            if (d[p2.first][p2.second] != -2 && V[p2.first][p2.second] > V[p1.first][p1.second] + 1)
            {
                V[p2.first][p2.second] = V[p1.first][p1.second] + 1;
                q.push(p2);
            }
        }
    }
}

void write()
{
    freopen(FOUT, "w", stdout);
    if (answer == INF)
        printf("-1\n");
    else
        printf("%d\n", answer);
}

int BFS2(int m)
{
    pair <int, int> p1,p2;

    while (!q.empty())
        q.pop();

    for (int  i = 0; i <= r; ++i)
        d[i][0] = d[i][c + 1] = -2;
    for (int i = 0; i <= c; ++i)
        d[0][i] = d[r + 1][i] = -2;
    for (int i = 1; i <= r; ++i)
        for (int j = 1; j <= c; ++j)
            if (d[i][j] != -2)
                d[i][j] = INF;

    q.push(b);
    d[b.first][b.second] = dist[b.first][b.second];

    while (!q.empty())
    {
        p1 = q.front();
        q.pop();
        for (int i = 0; i < 4; ++i)
        {
            p2 = make_pair(p1.first + dx[i], p1.second + dy[i]);
            if (dist[p2.first][p2.second] >= m && d[p2.first][p2.second] == INF)
            {
                d[p2.first][p2.second] = min(d[p1.first][p1.second], dist[p2.first][p2.second]);
                q.push(p2);
            }
        }
    }
    return d[e.first][e.second];
}

void binarysearch()
{
    int p = 0, u = (r * c), m, x;

    while (p < u)
    {
        m = (p + u) / 2;
        x = BFS2(m);
        if (x == INF || x == -2 || x < m)
        {
            u = m;
        }
        else
        {
            p = m + 1;
            if (m > answer)
                answer = m;
        }
    }
}

int main()
{
    read();

    BFS(dist);

    binarysearch();

    write();
}