Cod sursa(job #1597368)

Utilizator DrumeaVDrumea Vasile DrumeaV Data 11 februarie 2016 22:05:17
Problema Barbar Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.32 kb
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>

#define pii pair< int,int >
#define st first
#define nd second

using namespace std;

const int Mn = 1e3 + 4;
const int dx[] = {-1,0,1,0};
const int dy[] = {0,1,0,-1};

int n,m,sol,xs,ys,xf,yf,it;
int dst[Mn][Mn],used[Mn][Mn];
char ar[Mn][Mn];
queue< pii > q;

bool ok(int i,int j)
{
    return (i > 0 && j > 0 && i <= n && j <= m && (ar[i][j] != '*'));
}

void bfs()
{
    while (!q.empty())
    {
        int x = q.front().st,y = q.front().nd;
        q.pop();

        for (int it = 0;it < 4;it++)
        {
            int xx = x + dx[it],yy = y + dy[it];
            if (ok(xx,yy) && (dst[xx][yy] == 0 | dst[xx][yy] > dst[x][y] + 1))
            {
                dst[xx][yy] = dst[x][y] + 1;
                q.push(make_pair(xx,yy));
            }
        }
    }
}

bool check(int val)
{
    q.push(make_pair(xs,ys));
    used[xs][ys] = it + 1;
    if (dst[xs][ys] < val)
       return 0;

    while (!q.empty())
    {
        int x = q.front().st,y = q.front().nd;
        q.pop();

        for (int it = 0;it < 4;it++)
        {
            int xx = x + dx[it],yy = y + dy[it];
            if (ok(xx,yy) && used[xx][yy] <= it && dst[xx][yy] >= val)
            {
                if (xx == xf && yy == yf)
                   return 1;

                used[xx][yy] = it + 1;
                q.push(make_pair(xx,yy));
            }
        }
    }

    return 0;
}

int main()
{
    freopen("barbar.in","r",stdin);
    freopen("barbar.out","w",stdout);

    scanf("%d %d",&n,&m);
    for (int i = 1;i <= n;i++)
    {
        scanf("%s",ar[i] + 1);
        for (int j = 1;j <= m;j++)
        {
            if (ar[i][j] == 'D')
               q.push(make_pair(i,j)),dst[i][j] = 1;

            if (ar[i][j] == 'I')
               xs = i,ys = j;

            if (ar[i][j] == 'O')
               xf = i,yf = j;
        }
    }

    bfs();
    for (int i = 1;i <= n;i++)
        for (int j = 1;j <= m;dst[i][j]--,j++);

    int l = 0,r = 1000;
    for (;l <= r;it++)
    {
        int m = (l + r) / 2;
        if (check(m))
        {
            sol = m - 1;
            l = m + 1;
        }
      else
            r = m - 1;
    }

    printf("%d\n",sol);

  return 0;
}