Pagini recente » Cod sursa (job #1788504) | Cod sursa (job #2813948) | Cod sursa (job #367842) | Cod sursa (job #2793392) | Cod sursa (job #2543792)
#include <fstream>
#include <queue>
using namespace std;
ifstream f("barbar.in");
ofstream g("barbar.out");
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int n,m,a[1005][1005],b[1005][1005],d[1005][1005],xi,yi,xf,yf;
queue <pair<int,int>> q;
void bordare(int n, int m)
{
for(int i=0;i<=n+1;i++)
{
a[i][0]=a[i][m+1]=b[i][0]=b[i][m+1]=d[i][0]=d[i][m+1]=-1;
}
for(int i=0;i<=m+1;i++)
{
a[0][i]=a[n+1][i]=b[0][i]=b[n+1][i]=d[0][i]=d[n+1][i]=-1;
}
}
void reset()
{
for(int i=0;i<=n+1;i++)
{
for(int j=0;j<=m+1;j++)
{
a[i][j]=b[i][j];
}
}
}
void Fill(int i, int j, int dst)
{
a[i][j]=-1;
for(int p=0;p<4;p++)
{
int xx=i+dx[p];
int yy=j+dy[p];
if(!a[xx][yy] && d[xx][yy]-1>=dst)
{
Fill(xx,yy,dst);
}
}
}
void Lee()
{
while(!q.empty())
{
int x=q.front().first;
int y=q.front().second;
q.pop();
for(int i=0;i<4;i++)
{
int xx=x+dx[i];
int yy=y+dy[i];
if(!d[xx][yy])
{
q.push({xx,yy});
d[xx][yy]=d[x][y]+1;
}
}
}
/// acum stim pentru fiecare celula cat de apropiat e cel mai apropiat dragon
}
int main()
{
///personajul principal o sa fie Jonel pentru ca suna mai bine decat Paftenie
f>>n>>m;
bordare(n,m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
char ch;
f>>ch;
if(ch=='I') ///de aici pleaca Jonel
{
xi=i;
yi=j;
}
else if(ch=='O') ///aici ajunge Jonel
{
xf=i;
yf=j;
}
else if(ch=='*') ///pe aici nu poate trece Jonel
{
a[i][j]=-1;
b[i][j]=-1; ///"b" va ramane mereu matricea initiala, o vom folosi pentru a reseta matricea "a" dupa ce aceasta din urma va fi stricata
d[i][j]=-1;
}
else if(ch=='D') ///de asta fuge Jonel
{
q.push({i,j}); ///punem in coada ca de fiecare data sa stim cat de aproape de Jonel e un dragon
d[i][j]=1;
}
}
}
Lee(); ///calculam distantele fata de Jonel
///cautam binar distanta, folosind algoritmul de Fill pentru a afla daca distanta e prea mare sau nu
/// daca e prea mare, adica Jonel nu va ajunge la iesire pastrand distanta, vom continua cautarea in intervalul st,mij-1, altfel in intervalul mij+1,dr
int st=0,dr=d[xi][yi];
int rez=0;
bool ok=false;
while(st<=dr)
{
int mij=(st+dr)/2;
reset();
Fill(xi,yi,mij);
if(a[xf][yf]==0)
{
dr=mij-1;
}
else
{
ok=true;
rez=mij;
st=mij+1;
}
}
if(ok)
g<<rez<<'\n';
else g<<-1<<'\n';
return 0;
}