Cod sursa(job #1587993)

Utilizator stoianmihailStoian Mihail stoianmihail Data 2 februarie 2016 18:28:46
Problema Barbar Scor 90
Compilator c Status done
Runda Arhiva de probleme Marime 3.04 kb
#include <stdio.h>
#include <stdlib.h>

#define MAX_Q 1000000
#define Nadejde 1000
#define MAX_DIR 4
#define NIL -1

const int delta[MAX_DIR][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};

typedef struct {
  int l, c;
} pair;

int N, M;
int qhead, qtail;
pair start, finish;
pair queue[MAX_Q + 1];
int d[Nadejde + 2][Nadejde + 2];
char s[Nadejde + 2][Nadejde + 2];
pair boss[Nadejde + 2][Nadejde + 2];

void overFlow(int n, int m) {
  int i, j;

  for (i = 0; i <= n; i++) {
    d[i][0] = d[i][m] = NIL;
  }
  for (j = 0; j <= m; j++) {
    d[0][j] = d[n][j] = NIL;
  }
}

pair make(int l, int c) {
  pair tmp;
  tmp.l = l;
  tmp.c = c;
  return tmp;
}

void enqueue(int l, int c, int dist) {
  queue[qtail++] = make(l, c);
  d[l][c] = dist;
}

void dequeue(int *l, int *c, int *dist) {
  (*l) = queue[qhead].l;
  (*c) = queue[qhead++].c;
  (*dist) = d[(*l)][(*c)] + 1;
}

void init() {
  int i, l, c, l0, c0, dist;

  do {
    dequeue(&l, &c, &dist);
    for (i = 0; i < MAX_DIR; i++) {
      l0 = l + delta[i][0];
      c0 = c + delta[i][1];
      if (!d[l0][c0]) {
        enqueue(l0, c0, dist);
      }
    }
  } while (qhead != qtail);
}

int equal(pair X, pair Y) {
  return ((X.l == Y.l) && (X.c == Y.c));
}

pair find(pair u) {
  pair r, next;

  for (r = u; !equal(boss[r.l][r.c], r); r = boss[r.l][r.c]);
  for (; !equal(boss[u.l][u.c], u); u = next) {
    next = boss[u.l][u.c];
    boss[u.l][u.c] = r;
  }
  return r;
}

void unify(pair u, pair v) {
  pair ru = find(u), rv = find(v);

  if (!equal(ru, rv)) {
    boss[rv.l][rv.c] = ru;
  }
}

void connect(pair loc) {
  int i;
  pair next;

  for (i = 0; i < MAX_DIR; i++) {
    next = make(loc.l + delta[i][0], loc.c + delta[i][1]);
    if (d[next.l][next.c] >= d[loc.l][loc.c]) {
      unify(loc, next);
    }
  }
}

int escaped() {
  return equal(find(start), find(finish));
}

void fire() {
  int i, j, dist;

  for (i = qtail - 1; i >= 0;) {
    dist = d[queue[i].l][queue[i].c];
    //fprintf(stderr, "%d\n", dist);
    for (j = i; d[queue[j].l][queue[j].c] == dist; j--) {
      connect(queue[j]);
    }
    i = j;
    if (escaped()) {
      fprintf(stdout, "%d\n", dist - 1);
      exit(0);
    }
  }
}

int main(void) {
  int i, j;
  FILE *f = fopen("barbar.in", "r");

  fscanf(f, "%d %d", &N, &M);
  for (i = 1; i <= N; i++) {
    fscanf(f, "%s", s[i] + 1);
    for (j = 1; j <= M; j++) {
      boss[i][j] = make(i, j);
      if (s[i][j] == 'I') {
        start = make(i, j);
      } else if (s[i][j] == 'O') {
        finish = make(i, j);
      } else if (s[i][j] == 'D') {
        enqueue(i, j, 1);
      } else if (s[i][j] == '*') {
        d[i][j] = NIL;
      }
    }
  }
  fclose(f);

  //fprintf(stderr, "start = (%d, %d) si finish = (%d, %d)\n", start.l, start.c, finish.l, finish.c);

  overFlow(N + 1, M + 1);
  init();

  freopen("barbar.out", "w", stdout);
  /*for (i = 0; i <= 0+N; i++) {
    for (j = 0; j <= 0+M; j++) {
      fprintf(stdout, "%d ", d[i][j]);
    }
    fprintf(stdout, "\n");
  }
*/
  fire();

  //freopen("barbar.out", "w", stdout);
  fclose(stdout);

  /// Multumim Doamne!
  puts("Doamne ajuta!");
  return 0;
}