Cod sursa(job #184763)

Utilizator floringh06Florin Ghesu floringh06 Data 24 aprilie 2008 11:30:03
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.58 kb
#include <cstdio>
#include <cstring>

using namespace std;

#define FIN "barbar.in"
#define FOUT "barbar.out"
#define MOD 100000

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 100005

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;
    }