Cod sursa(job #2697002)

Utilizator bogdan.gusuleacGusuleac Bogdan bogdan.gusuleac Data 17 ianuarie 2021 14:57:12
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.9 kb
#include <bits/stdc++.h>

using namespace std;

fstream fin("barbar.in", ios::in);
fstream fout("barbar.out", ios::out);

typedef pair <int, int> p;

int dx[] = { -1, 1, 0, 0 };
int dy[] = { 0, 0, 1, -1 };

#define MAXSIZE 1024

char a[MAXSIZE][MAXSIZE], vizitat[MAXSIZE][MAXSIZE];
int dist[MAXSIZE][MAXSIZE], n, m, xp, yp, xo, yo;

queue<p> q;

inline bool ok(int x, int y)
{
	return x && y && x <= n && y <= m && vizitat[x][y] == 0;
}

void Lee()
{
	while (!q.empty())
	{
		int x = q.front().first, y = q.front().second;
		q.pop();

		vizitat[x][y] = 1;
		for (int i = 0; i < 4; ++i)
		{
			int nx = x + dx[i], ny = y + dy[i];
			if (ok(nx, ny) && a[nx][ny] != '*' && dist[nx][ny] == 0)
			{
				dist[nx][ny] = dist[x][y] + 1;
				q.push({ nx, ny });
			}
		}
	}
}

inline bool validare(int val)
{
	memset(vizitat, 0, sizeof vizitat);
	queue <p> coada;
	coada.push({ xp, yp });

	while (!coada.empty())
	{
		int x = coada.front().first, y = coada.front().second;
		coada.pop();
		vizitat[x][y] = 1;
		for (int i = 0; i < 4; ++i)
		{
			int nx = x + dx[i], ny = y + dy[i];
			if (ok(nx, ny) && dist[nx][ny] >= val)
			{
				vizitat[nx][ny] = 1;
				if (nx == xo && ny == yo)
					return 1;
				coada.push({ nx, ny });
			}
		}
	}
	return 0;
}

int main()
{
	fin >> n >> m;
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= m; ++j)
		{
			fin >> a[i][j];
			if (a[i][j] == 'D')
			{
				vizitat[i][j] = 1;
				q.push({ i, j });
			}
			else if (a[i][j] == 'I')
			{
				xp = i;
				yp = j;
			}
			else if (a[i][j] == 'O')
			{
				xo = i;
				yo = j;
			}
		}

	Lee();

	int m = 0, st = 0, dr = dist[xp][yp], bun = 0;

	while (st <= dr)
	{
		m = (st + dr) / 2;
		if (validare(m))
		{
			if (m > bun)
				bun = m;
			st = m + 1;
		}
		else dr = m - 1;
	}

	if (bun == 0) fout << "-1\n";
	else fout << bun << "\n";

	return 0;
}