Cod sursa(job #2671956)

Utilizator killerdonuttudor nicolae killerdonut Data 12 noiembrie 2020 21:24:12
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.49 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] != -2)
		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++)
	{
		int 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;
}