Cod sursa(job #783013)

Utilizator visanrVisan Radu visanr Data 1 septembrie 2012 23:03:15
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.69 kb
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;

#define inf 0x3f3f3f3f
#define nmax 1010
#define mp make_pair
#define x first
#define y second

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

int N, M, Sx, Sy, Dx, Dy, mat[nmax][nmax], Dist[nmax][nmax], Path[nmax][nmax], ans;
char s[nmax];


void Lee1()
{
     queue<pair<int, int> > Q;
     int i, j;
     pair<int, int> old;
     for(i = 1; i <= N; i++)
           for(j = 1; j <= M; j++)
                 if(mat[i][j] == -3)
                              Q.push(mp(i, j));
     while(!Q.empty())
     {
                     old = Q.front();
                     Q.pop();
                     for(i = 0; i < 4; i++)
                     {
                           int ll = old.x + dx[i];
                           int cc = old.y + dy[i];
                           if(1 <= ll && ll <= N && 1 <= cc && cc <= M)
                                if(Dist[ll][cc] == 0 || Dist[old.x][old.y] + 1 < Dist[ll][cc])
                                {
                                                Dist[ll][cc] = Dist[old.x][old.y] + 1;
                                                Q.push(mp(ll, cc));
                                }
                     }
     }
}

int Lee2(int val)
{
     if(Dist[Sx][Sy] < val) return 0;
     queue<pair<int, int> > Q;
     pair<int, int> old;
     int i;
     Q.push(mp(Sx, Sy));
     while(!Q.empty())
     {
                   old = Q.front();
                   Q.pop();
                   for(i = 0; i < 4; i++)
                   {
                         int ll = old.x + dx[i];
                         int cc = old.y + dy[i];
                         if(1 <= ll && ll <= N && 1 <= cc && cc <= M)
                              if(Dist[ll][cc] >= val && mat[ll][cc] != val && mat[ll][cc] >= 0)
                              {
                                              Q.push(mp(ll, cc));
                                              mat[ll][cc] = val;
                                              if(ll == Dx && cc == Dy) 
                                              {
                                                    while(!Q.empty()) Q.pop();
                                                    return 1;
                                              }
                              }
                   }
     }
     return 0;
}

void BS(int left, int right)
{
    if(left == right)
    {
            if(left > ans && Lee2(left))
                    ans = left;
            return ;
    }
    int mid = (left + right) / 2;
    if(Lee2(mid)) 
    {
                  ans = max(ans, mid);
                  BS(mid + 1, right);
    }else
         BS(left, mid);
}

int main()
{
    freopen("barbar.in", "r", stdin);
    freopen("barbar.out", "w", stdout);
    int i, j;
    scanf("%i %i\n", &N, &M);
    for(i = 1; i <= N; i++)
    {
          gets(s);
          int lg = strlen(s);
          for(j = 0; j < lg; j++)
          {
                if(s[j] == '.') 
                        mat[i][j + 1] = Dist[i][j + 1] = 0;
                if(s[j] == '*')
                        mat[i][j + 1] = Dist[i][j + 1] = -1;
                if(s[j] == 'I')
                        Sx = i, Sy = j + 1;
                if(s[j] == 'D')
                        mat[i][j + 1] = -3, Dist[i][j + 1] = 1;
                if(s[j] == 'O')
                        Dx = i, Dy = j + 1;
          }
    }     
    Lee1();
    BS(1, Dist[Dx][Dy]);
    printf("%i\n", ans - 1);
    return 0;
}