Cod sursa(job #593095)

Utilizator darrenRares Buhai darren Data 1 iunie 2011 11:56:54
Problema Barbar Scor 100
Compilator cpp Status done
Runda pregatire_lot_juniori_1 Marime 2.35 kb
#include <cstring>
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

const int d1[] = {1, 0, -1, 0},
          d2[] = {0, 1, 0, -1};

inline int abs(int x)
{
	return x < 0 ? -x : x;
}

bool Test(int x);
bool Ok(pair<int, int> p);

int n, m;
queue<pair<int, int> > dr, q;
vector<pair<int, int> > d;
int can[1001][1001], ncan[1001][1001];
pair<int, int> st, fn;
int res = -1;

int main()
{
	ifstream fin("barbar.in");
	ofstream fout("barbar.out");
	
	fin >> n >> m;
	
	char str[1005];
	fin.getline(str, 1002);
	
	for (int i = 1; i <= n; ++i)
	{
		fin.getline(str, 1002);
		for (int j = m; j >= 1; --j)
		{
			str[j] = str[j - 1];
			if (str[j] == 'D')
				d.push_back(make_pair(i, j)), can[i][j] = -1;
			else if (str[j] == '*')
				can[i][j] = -1;
			else if (str[j] == 'I')
				st = make_pair(i, j);
			else if (str[j] == 'O')
				fn = make_pair(i, j);
		}
	}
	
	int aux = max(n, m), step;
	for (step = 1; (step << 1) <= aux; step <<= 1);
	for (int i = 0; step; step >>= 1)
		if (i + step <= aux && Test(i + step))
			i += step, res = i;
	
	fout << res;
	
	fin.close();
	fout.close();
}

bool Test(int x)
{
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= m; ++j)
			ncan[i][j] = can[i][j];
	
	for (int i = 0; i < d.size(); ++i)
		dr.push(d[i]);
	while (!dr.empty())
	{
		pair<int, int> now = dr.front(), aux; dr.pop();
		if (abs(ncan[now.first][now.second]) == x)
			continue;
		
		for (int k = 0; k < 4; ++k)
		{
			aux = now;
			aux.first += d1[k], aux.second += d2[k];
			if (Ok(aux))
			{
				ncan[aux.first][aux.second] = ncan[now.first][now.second] - 1;
				dr.push(aux);
			}
		}
	}
	
	if (ncan[st.first][st.second] != 0) return false;
	ncan[st.first][st.second] = 1;
	
	while (!q.empty()) q.pop();
	q.push(st);
	while (!q.empty())
	{
		pair<int, int> now = q.front(), aux; q.pop();
		
		for (int k = 0; k < 4; ++k)
		{
			aux = now;
			aux.first += d1[k], aux.second += d2[k];
			if (Ok(aux))
			{
				ncan[aux.first][aux.second] = ncan[now.first][now.second];
				q.push(aux);
				
				if (aux == fn) return true;
			}
		}
	}
	
	return false;
}

bool Ok(pair<int, int> p)
{
	if (p.first < 1 || p.first > n || p.second < 1 || p.second > m) return false;
	if (ncan[p.first][p.second] != 0) return false;
	return true;
}