Pagini recente » Cod sursa (job #650707) | Cod sursa (job #1304451) | Cod sursa (job #375370) | Cod sursa (job #1419264) | Cod sursa (job #1887371)
#include <fstream>
#define in "barbar.in"
#define out "barbar.out"
#define NM 1003
#define oo 2000000000
using namespace std;
ifstream fin(in);
ofstream fout(out);
int n,m;
char c[NM][NM];
bool v[NM][NM];
int dmin[NM][NM]; // pentru fiecare casuta vedem drumul minim pana la primul dragon
struct Pc{
int i,j;
}coada[NM*NM],A,B;
int diri[]={-1,0,1,0};
int dirj[]={0,1,0,-1};
void LeeD()
{
int st,dr;
dr = 0;
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
if(c[i][j] == 'D')
{
++dr;
coada[dr].i = i;
coada[dr].j = j;
v[i][j] = 1;
}
st = 1;
int I,J;
while(st<=dr)
{
for(int k=0; k<4; ++k)
{
I = coada[st].i + diri[k];
J = coada[st].j + dirj[k];
if(!dmin[I][J] && c[I][J] != '*' && c[I][J] != 'D')
{
dmin[I][J] = dmin[coada[st].i][coada[st].j] + 1;
++dr;
coada[dr].i = I;
coada[dr].j =J;
}
}
++st;
}
}
void Bordare()
{
for(int j=1; j<=m; ++j)
c[0][j] = c[n+1][j] = '*';
for(int i=1; i<=n; ++i)
c[i][0] = c[i][m+1] = '*';
}
inline bool posib(int I,int J,int r)
{
if(v[I][J] == 1) return 0;
if(c[I][J] == '*' || c[I][J] == 'D') return 0;
if(dmin[I][J] < r) return 0;
return 1;
}
inline void memsett()
{
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
v[i][j] = 0;
}
inline bool LeeEok(int r)
{
memsett();
int st,dr;
st = dr = 1;
if(!posib(A.i,A.j,r)) return 0;
v[A.i][A.j] = 1;
coada[st].i = A.i;
coada[st].j = A.j;
int I,J;
while(st<=dr)
{
for(int k=0; k<4; ++k)
{
I = coada[st].i + diri[k];
J = coada[st].j + dirj[k];
if(posib(I,J,r))
{
v[I][J] = 1;
++dr;
coada[dr].i = I;
coada[dr].j =J;
}
}
++st;
}
if(v[B.i][B.j] == 1) return true;
return false;
}
int LgMin()
{
if(!LeeEok(0)) return -1;
int rez = 0;
int st,dr,mij;
st = 1; dr = max(n,m);
while(st<=dr)
{
mij = (st+dr)/2;
if(LeeEok(mij))
{
rez = max(rez,mij);
st = mij +1;
}
else
dr = mij - 1;
}
return rez;
}
void afisare()
{
for(int i=1; i<=n; ++i)
{
for(int j=1; j<=m; ++j)
fout<<dmin[i][j]<<" ";
fout<<"\n";
}
}
int main()
{
fin>>n>>m;
fin.get();
int i,j;
for(i=1; i<=n; ++i)
{
for(j=1; j<=m; ++j)
{
fin>>c[i][j];
if(c[i][j] == 'I')
A.i = i, A.j = j;
if(c[i][j] == 'O')
B.i = i, B.j = j;
}
fin.get();
}
Bordare();
LeeD();
//afisare();
fout<<LgMin();
fin.close(); fout.close();
return 0;
}