Cod sursa(job #193040)

Utilizator floringh06Florin Ghesu floringh06 Data 1 iunie 2008 22:33:46
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.39 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;      
    }