Cod sursa(job #783003)

Utilizator visanrVisan Radu visanr Data 1 septembrie 2012 22:52:45
Problema Barbar Scor 80
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];
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)), Dist[i][j] = 0;
                 else if(mat[i][j] == -1) Dist[i][j] = -1;
                 else Dist[i][j] = inf;
           }
     }
     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] != -1)
                              {
                                              Q.push(mp(ll, cc));
                                              mat[ll][cc] = val;
                                              if(ll == Dx && cc == Dy) 
                                                    return 1;
                              }
                   }
     }
     return 0;
}

int BS()
{
    int left = 0, right = N * M, mid, ans = inf;
    while(left <= right)
    {
               mid = (left + right) / 2;
               if(Lee2(mid)) 
               {
                             ans = mid;
                             left = mid + 1;
               }else
               {
                    right = mid - 1;
               }
    }
    return ans;
}

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();
    printf("%i\n", BS());
    return 0;
}