Pagini recente » Cod sursa (job #1269934) | Cod sursa (job #167235) | Cod sursa (job #2449306) | Cod sursa (job #1979994) | Cod sursa (job #2480742)
#include <bits/stdc++.h>
using namespace std;
pair<int, int> v[1000005];
char a[1005][1005];
int b[1005][1005], n, m, k;
int xi, yi, xo, yo;
/// b[i][j] = distanta minima posibila de la poz.
/// (i, j) la un dragon
bitset<1003> c[1003];
ifstream fin("barbar.in");
ofstream fout("barbar.out");
inline void Citire()
{
fin >> n >> m;
for (int i = 1; i <= n; i++)
fin >> (a[i] + 1);
}
inline void Bordare()
{
int i;
/// bordez coloanele 0 si m + 1
for (i = 0; i <= n + 1; i++)
a[i][0] = a[i][m + 1] = '*';
/// bordez liniile 0 si n + 1
for (i = 0; i <= m + 1; i++)
a[0][i] = a[n + 1][i] = '*';
}
inline void Initial()
{
int i, j;
for (i = 1; i <= n; i++)
for (j = 1; j <= m; j++)
{
if (a[i][j] == 'I') {xi = i; yi = j;}
if (a[i][j] == 'O') {xo = i; yo = j;}
if (a[i][j] == 'D')
{
b[i][j] = 0;
k++;
v[k] = {i, j}; /// am retinut poziile lui D
}
else b[i][j] = 2000000;
}
}
inline void Distante()
{
int i, j, x, y;
while (k > 0)
{
i = v[k].first;
j = v[k].second;
k--;
/// nord:
x = i - 1;
y = j;
if (a[x][y] != '*' && b[x][y] > 1 + b[i][j])
{
b[x][y] = 1 + b[i][j];
k++;
v[k] = {x, y};
}
/// sud:
x = i + 1;
y = j;
if (a[x][y] != '*' && b[x][y] > 1 + b[i][j])
{
b[x][y] = 1 + b[i][j];
k++;
v[k] = {x, y};
}
/// est:
x = i;
y = j + 1;
if (a[x][y] != '*' && b[x][y] > 1 + b[i][j])
{
b[x][y] = 1 + b[i][j];
k++;
v[k] = {x, y};
}
/// vest:
x = i;
y = j - 1;
if (a[x][y] != '*' && b[x][y] > 1 + b[i][j])
{
b[x][y] = 1 + b[i][j];
k++;
v[k] = {x, y};
}
}
}
inline void Afisare()
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
if (b[i][j] != 2000000)fout << b[i][j] << " ";
else fout << "X ";
fout << "\n";
}
}
/// Verific daca pot ajunge de la I la O
/// mergand doar pe valori >= Val
inline void Fill(short i, short j, int Val)
{
if (a[i][j] != '*' && b[i][j] >= Val && c[i][j] == 0)
{
c[i][j] = 1;
Fill(i - 1, j, Val);
Fill(i + 1, j, Val);
Fill(i, j - 1, Val);
Fill(i, j + 1, Val);
}
}
inline void CautBin()
{
int st, dr, mij, Val;
st = 1; dr = b[xi][yi];
while(st <= dr)
{
mij = (st + dr)/ 2;
for(int i = 1; i <=n; i++)
c[i].reset();
Fill(xi, yi, mij);
if(c[xo][yo] == 1)
{
Val = mij;
st = mij + 1;
}
else dr = mij -1;
}
fout << Val << "\n";
fout.close();
}
inline void Rezolva()
{
int Val, i;
for (Val = b[xi][yi]; Val >= 1; Val--)
{
for (i = 1; i <= n; i++)
c[i].reset();
/// incerc sa vad daca pot ajunge in (xi,yi)
/// in (xo, yo) mergand doar pe valori >= Val
Fill(xi, yi, Val);
if (c[xo][yo] == 1)
{
fout << Val << "\n";
fout.close();
return;
}
}
fout << "-1\n";
fout.close();
}
int main()
{
Citire();
Bordare();
Initial();
Distante();
CautBin();
return 0;
}