Cod sursa(job #973019)

Utilizator toranagahVlad Badelita toranagah Data 13 iulie 2013 09:49:37
Problema Barbar Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.67 kb
#include <algorithm>
#include <fstream>
#include <iostream>
#include <queue>
#include <string>
#include <vector>
using namespace std;

struct Point {int x, y;};

ifstream fin("barbar.in");
ofstream fout("barbar.out");

const int MAX_N = 1005;
const int INF = 1 << 30;
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};

int N, M;
Point SOURCE, DESTINATION;
int d[MAX_N][MAX_N]; 
bool visited[MAX_N][MAX_N];
int answer;

void read_input();
void solve();
void print_output();
bool bfs(int min_val);

int main() {
  read_input();
  solve();
  print_output();
  return 0;
}

void read_input() {
  fin >> N >> M;
  fin.ignore();
  string row;
  for (int i = 0; i < N; ++i) {
    getline(fin, row);
    for (int j = 0; j < M; ++j) {
      if (row[j] == 'D') {
        d[i + 1][j + 1] = 0;
      } else if (row[j] == '*') {
		d[i + 1][j + 1] = -1;
	  } else {
        d[i + 1][j + 1] = INF;
        if (row[j] == 'I') {
          SOURCE = {i + 1, j + 1};
        }
        if (row[j] == 'O') {
          DESTINATION = {i + 1, j + 1};
        }
      }
    }
  }
}

void solve() {
  for (int i = 0; i <= N + 1; ++i)
    d[i][0] = d[i][M + 1] = -1;
  for (int j = 0; j <= M + 1; ++j)
    d[0][j] = d[N + 1][j] = -1;

  queue<Point> q;
  for (int i = 1; i <= N; ++i) {
    for (int j = 1; j <= M; ++j) {
	  if (d[i][j] == 0) {
		q.push({i, j});
	  }
	  visited[i][j] = false;
	}
  }

  while (!q.empty()) {
    int x = q.front().x;
    int y = q.front().y;
    q.pop();
    for (int k = 0; k < 4; ++k) {
      int xx = x + dx[k];
      int yy = y + dy[k];
      if (d[xx][yy] != -1 && d[x][y] + 1 < d[xx][yy]) {
        d[xx][yy] = d[x][y] + 1;
        q.push({xx, yy});
      }
    }
  }

  int lo = 0, hi = N + M + 1;
  while (lo <= hi) {
    int mid = lo + (hi - lo) / 2;
    if (bfs(mid)) {
      answer = lo;
      lo = mid + 1;
    } else {
      hi = mid - 1;
    }
  }

  if (!bfs(answer)) {
    answer = -1;
  }

}

void print_output() {
  fout << answer;
}

bool bfs(int min_val) {
  if (d[SOURCE.x][SOURCE.y] < min_val) 
    return false;

  for (int i = 1; i <= N; ++i) {
    for (int j = 1; j <= M; ++j) {
        visited[i][j] = 0;
    }
  }

  queue<Point> q;
  q.push(SOURCE);
  visited[SOURCE.x][SOURCE.y] = true;

  while (!q.empty()) {
    int x = q.front().x;
    int y = q.front().y;
    q.pop();

    for (int k = 0; k < 4; ++k) {
      int xx = x + dx[k];
      int yy = y + dy[k];
      if (d[xx][yy] != -1) {
        if (d[xx][yy] >= min_val && !visited[xx][yy]) {
          visited[xx][yy] = true;
          q.push({xx, yy});
          if (xx == DESTINATION.x && yy == DESTINATION.y) {
            return true;
          }
        }
      }
    }
  }
  return visited[DESTINATION.x][DESTINATION.y];
}