Cod sursa(job #293804)

Utilizator floringh06Florin Ghesu floringh06 Data 2 aprilie 2009 08:26:22
Problema Barbar Scor 100
Compilator cpp Status done
Runda high_level_contest2 Marime 4.79 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;         
    }