Pagini recente » Cod sursa (job #273276) | Cod sursa (job #2825602) | Cod sursa (job #1673296) | Cod sursa (job #768728) | Cod sursa (job #1000377)
#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;
}