Cod sursa(job #2053478)

Utilizator trifangrobertRobert Trifan trifangrobert Data 31 octombrie 2017 20:04:50
Problema Barbar Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.36 kb
#include <iostream>
#include <conio.h>

#include <fstream>
#include <queue>
#define DIM 1010
#define INF 2000000000

using namespace std;

int dx[] = {0, 0, -1, 1};
int dy[] = {-1, 1, 0, 0};
int n, m;
short a[DIM][DIM];
int dr[DIM][DIM];
int startx, starty, finishx, finishy;

void Read()
{
	ifstream fin("barbar.in");
	char s[DIM];
	fin >> n >> m;
	fin.get();
	for (int i = 1;i <= n;++i)
	{
		fin.getline(s + 1, DIM);
		for (int j = 1;j <= m;++j)
		{
			if (s[j] == '.')
				a[i][j] = 0;
			if (s[j] == '*')
				a[i][j] = 1;
			if (s[j] == 'I')
			{
				startx = i;
				starty = j;
			}
			if (s[j] == 'O')
			{
				finishx = i;
				finishy = j;
			}
			if (s[j] == 'D')
				a[i][j] = 2;
		}
	}
}

inline bool Verify(int i, int j)
{
	return 1 <= i && i <= n && 1 <= j && j <= m;
}

void LeeDragons()
{
	queue <pair <int, int> > q;
	for (int i = 1;i <= n;++i)
		for (int j = 1;j <= m;++j)
			if (a[i][j] != 2)
				dr[i][j] = INF;
			else
			{
				dr[i][j] = 1;
				q.push(make_pair(i, j));
			}
	int i, j, x, y, k;
	while (!q.empty())
	{
		i = q.front().first;
		j = q.front().second;
		q.pop();
		for (k = 0;k < 4;++k)
		{
			x = i + dx[k];
			y = j + dy[k];
			if (Verify(x, y) && dr[x][y] > dr[i][j] + 1)
			{
				dr[x][y] = dr[i][j] + 1;
				q.push(make_pair(x, y));
			}
		}
	}
}

int Lee(int dist)
{
	if (dr[startx][starty] <= dist)
		return false;
	bool d[DIM][DIM];
	for (int i = 1;i <= n;++i)
		for (int j = 1;j <= m;++j)
			d[i][j] = false;
	queue <pair <int, int> > q;
	q.push(make_pair(startx, starty));
	d[startx][starty] = true;
	int i, j, x, y, k;
	while (!q.empty())
	{
		i = q.front().first;
		j = q.front().second;
		q.pop();
		for (k = 0;k < 4;++k)
		{
			x = i + dx[k];
			y = j + dy[k];
			if (Verify(x, y) && d[x][y] == false && a[i][j] == 0 && dr[x][y] > dist)
			{
				d[x][y] = true;
				q.push(make_pair(x, y));
			}
		}
	}	
	return d[finishx][finishy];
}

int BinarySearch()
{
	int left = 1, right = DIM, mid, poz = -1;
	while (left <= right)
	{
		mid = (left + right) / 2;
		if (Lee(mid))
		{
			poz = mid;
			left = mid + 1;
		}
		else
			right = mid - 1;
	}
	return poz;
}

void Write()
{
	ofstream fout("barbar.out");
	fout << BinarySearch() << "\n";
	fout.close();
}

int main()
{
	Read();
	LeeDragons();
	Write();
	_getch();
	return 0;
}