Cod sursa(job #2309336)

Utilizator killerdonuts358nicolae tudor killerdonuts358 Data 28 decembrie 2018 20:42:16
Problema Barbar Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.47 kb
#include <fstream>
#include <string>
#include <queue>

using namespace std;

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

const int N = 1003;
const int di[4] = { 1,0,-1,0 };
const int dj[4] = { 0,1,0,-1 };

queue < pair <int, int> > q, cost;
int n, m, z[N][N];
bool viz[N][N];
string a;
pair <int, int> start, finish;

bool OK(int i, int j)
{
	if (i > 0 && j > 0 && i <= n && j <= m && z[i][j] == -1)
		return true;

	return false;
}

bool OK2(int i, int j)
{
	if (i > 0 && j > 0 && i <= n && j <= m && viz[i][j] == false && z[i][j] >= 0)
		return true;

	return false;
}

void Lee()
{
	int x, y;
	int starti, startj;

	while (!q.empty())
	{
		starti = q.front().first;
		startj = q.front().second;

		for (int k = 0; k < 4; k++)
		{
			x = starti + di[k];
			y = startj + dj[k];

			if (OK(x, y))
			{
				q.push(make_pair(x, y));
				z[x][y] = z[starti][startj] + 1;
			}
		}

		q.pop();
	}
}

int Price(int thold)
{
	int x, y;
	int starti, startj;

	while (viz[finish.first][finish.second] == false)
	{
		if (!q.empty())
		{
			starti = q.front().first;
			startj = q.front().second;
			q.pop();
		}
		else if (!cost.empty())
		{
			starti = cost.front().first;
			startj = cost.front().second;
			cost.pop();
			thold = z[starti][startj];
		}
		else
			return -1;

		for (int k = 0; k < 4; k++)
		{
			x = starti + di[k];
			y = startj + dj[k];

			if (OK2(x, y))
			{
				if(z[x][y] >= thold)
					q.push(make_pair(x, y));
				else
					cost.push(make_pair(x, y));

				viz[x][y] = true;
			}
		}
	}

	return thold;
}


int main()
{
	fin >> n >> m;
	getline(fin, a);

	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			z[i][j] = -1;

	for (int i = 1; i <= n; i++)
	{
		unsigned find;
		getline(fin, a);
		find = a.find_first_not_of('.');

		while (find != string::npos)
		{
			if (a[find] == 'D')
			{
				q.push(make_pair(i, find + 1));
				z[i][find + 1] = 0;
			}
			else if (a[find] == '*')
			{
				z[i][find + 1] = -2;
			}
			else if (a[find] == 'I')
			{
				start = make_pair(i, find + 1);
			}
			else
			{
				finish = make_pair(i, find + 1);
			}

			a[find] = '.';
			find = a.find_first_not_of('.', find);
		}
	}

	Lee();

	q.push(start);
	viz[start.first][start.second] = true;
	int threshold = min(z[start.first][start.second], z[finish.first][finish.second]);
	threshold = Price(threshold);
	
	fout << threshold;

	return 0;
}