Cod sursa(job #185023)

Utilizator floringh06Florin Ghesu floringh06 Data 24 aprilie 2008 18:05:05
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.98 kb
#include <cstdio>   
#include <cstring>   
  
using namespace std;   
  
#define FIN "barbar.in"   
#define FOUT "barbar.out"   
#define MOD 200000   
  
const int dx[4] = {1, 0, -1, 0};   
const int dy[4] = {0, -1, 0, 1};   
  
#define MAX_N 1005   
  
unsigned char A[MAX_N][MAX_N];   
int Mat[MAX_N][MAX_N];   
  
#define MAX_C 200005   
  
typedef struct point { int x, y;};   
  
point C[MAX_C];   
int N, M;   
  
int li, lf;   
int Dmax, BEST; // solutii   
int inx, iny;   
int outx, outy;   
  
    void readdata ()   
    {   
         scanf ("%d %d\n", &N, &M);   
         int i, j, L;   
         char S[MAX_N];   
         for (i = 1; i <= N; ++i)   
         {    
             gets (S), L = strlen (S) - 1;   
             for (j = 0; j <= L; ++j)   
                  A[i][j + 1] = S[j];   
         }   
    }      
  
    inline int ok (int x, int y)   
    {   
           if (!x || !y || (x == N + 1) || (y == M + 1)) return 0;   
           return 1;   
    }     
       
    void dist ()   
    {   
         int i, j;   
         for (i = 1; i <= N; ++i)   
             for (j = 1; j <= M; ++j)   
             {   
                 if (A[i][j] == 'D') C[(++lf) % MOD].x = i, C[lf % MOD].y = j;   
                 if (A[i][j] == 'I') inx = i, iny = j;   
                 if (A[i][j] == 'O') outx = i, outy = j;   
         }   
            
         A[inx][iny] = A[outx][outy] = '.';   
            
         while (li < lf)   
         {   
               int x, y;   
               x = C[(++li) % MOD].x, y = C[(li) % MOD].y;   
                  
               for (i = 0; i < 4; ++i)   
                   if (A[x + dx[i]][y + dy[i]] == '.' && !Mat[x + dx[i]][y + dy[i]])   
                   {   
                      C[(++lf) % MOD].x = x + dx[i], C[lf % MOD].y = y + dy[i];   
                      Mat[x + dx[i]][y + dy[i]] = Mat[x][y] + 1;   
                      if (Mat[x][y] + 1 > Dmax) Dmax = Mat[x][y] + 1;   
                   }   
         }      
         for (i = 1; i <= N; ++i)   
             for (j = 1; j <= M; ++j)   
                 if (A[i][j] == 'D') Mat[i][j] = 0;   
    }            
       
    int path (int c)   
    {   
        int i;   
        li = lf = 0;   
           
        memset (A, 0, sizeof (A));   
           
        if (Mat[inx][iny] < c) return 0;   
           
        C[++lf].x = inx, C[lf].y = iny;   
           
        while (li < lf)   
        {   
              int x, y;   
              x = C[(++li) % MOD].x, y = C[li % MOD].y;   
                 
              for (i = 0; i < 4; ++i)   
                   if (A[x + dx[i]][y + dy[i]] == 0 && Mat[x + dx[i]][y + dy[i]] >= c && ok(x + dx[i], y + dy[i]))   
                  {   
                          C[(++lf) % MOD].x = x + dx[i], C[lf % MOD].y = y + dy[i];   
                          A[x + dx[i]][y + dy[i]] = 1;   
                             
                          if (x + dx[i] == outx && y + dy[i] == outy)   
                             return 1;   
                  }   
        }            
        return 0;        
    }   
  
    int main ()   
    {   
        freopen (FIN, "r", stdin);   
        freopen (FOUT, "w", stdout);   
           
        readdata ();   
        dist ();   
        /*  
        int i, j;          
        for (i = 1; i <= N; ++i)  
        {  
            for (j = 1; j <= M; ++j)  
                printf ("%d ", Mat[i][j]);  
            printf ("\n");  
        }  
        */  
        int st, dr, m;   
        st = 1, dr = Dmax;   
  
        BEST = -1;           
        while (st <= dr)   
        {   
              m = (st + dr) >> 1;   
                 
              int p = path (m);   
              if (p) BEST = m;   
              if (p) st = m + 1;   
                 else dr = m - 1;   
        }   
                 
        printf ("%d\n", (int) BEST);   
           
        return 0;   
    }