Cod sursa(job #460042)

Utilizator crawlerPuni Andrei Paul crawler Data 1 iunie 2010 01:00:32
Problema Barbar Scor 90
Compilator c Status done
Runda Arhiva de probleme Marime 2.05 kb
#include <stdio.h>
#include <string.h>

#define Nmax 1024

char a[Nmax][Nmax];
char v[Nmax][Nmax];
int minD[Nmax][Nmax], n,m;
int qx[Nmax*Nmax];
int qy[Nmax*Nmax];
int dx[] = {1,-1,0,0};
int dy[] = {0,0,1,-1};
int startx;
int starty;
int stopx;
int stopy;

inline int ok(int i, int j) {
  if (i < 1 || i > n)
    return 0;
  if (j < 1 || j > m)
    return 0;
  return 1;
}

int se_poate(int MIN) {
  if (minD[startx][starty] < MIN)
    return 0;

  int st = 0, dr = 1, i;
  qx[1] = startx;
  qy[1] = starty;
  v[startx][starty] = 1;
  memset(v, 0, sizeof v);
  
  while (st < dr) {
    ++st;
    for (i = 0; i < 4; ++i)
    if (  ok(qx[st]+dx[i], qy[st]+dy[i]))
    if (   a[qx[st]+dx[i]][qy[st]+dy[i]] != '*')
    if (minD[qx[st]+dx[i]][qy[st]+dy[i]] >= MIN)
    if (   v[qx[st]+dx[i]][qy[st]+dy[i]] == 0) {
      v[qx[st]+dx[i]][qy[st]+dy[i]] = 1;
      ++dr;
      qx[dr] = qx[st] + dx[i];
      qy[dr] = qy[st] + dy[i];
    }

  }

  return v[stopx][stopy];
}

int main() {
  freopen("barbar.in", "r", stdin);
  freopen("barbar.out", "w", stdout);
  
  scanf("%d%d\n", &n, &m);
  
  int i,j;
  
  for (i = 1; i <= n; ++i)
    scanf("%s", a[i]+1);
    
  int st = 0, dr = 0;
    
  for (i = 1; i <= n; ++i)
  for (j = 1; j <= m; ++j) {
    if (a[i][j] == 'D') {
      ++dr;
      qx[dr] = i;
      qy[dr] = j;
      v[i][j] = 1;
    }
    if (a[i][j] == 'I') {
      startx = i;
      starty = j;
    }
    if (a[i][j] == 'O') {
      stopx = i;
      stopy = j;
    }
  }

  while (st < dr) {
    ++st;
    for (i = 0; i < 4; ++i)
    if (ok(qx[st]+dx[i],qy[st]+dy[i]))
    if (a[qx[st]+dx[i]][qy[st]+dy[i]] != '*')
    if (v[qx[st]+dx[i]][qy[st]+dy[i]] == 0) {
      v[qx[st]+dx[i]][qy[st]+dy[i]] = 1;
      minD[qx[st]+dx[i]][qy[st]+dy[i]] = 1 + minD[qx[st]][qy[st]];
      ++dr;
      qx[dr] = qx[st] + dx[i];
      qy[dr] = qy[st] + dy[i];
    }
  }

  int ret = 0;
  
  for (i = 1<<20; i > 0; i/=2)
  if (se_poate(ret^i))
    ret ^= i;
    
  printf("%d\n", ret);
  
  return 0;
}