Pagini recente » Cod sursa (job #2560657) | Cod sursa (job #2629561) | Cod sursa (job #2986055) | Cod sursa (job #2374256) | Cod sursa (job #2696330)
#include <iostream>
#include <queue>
#include <string>
#include <algorithm>
#include <fstream>
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
int dx[] = { -1, 0, 0, 1 };
int dy[] = { 0, -1, 1, 0, };
int matrix[1002][1002], viz[1002][1002];
int n,m,k;
struct cell
{
int x,y;
cell(int x = 0, int y = 0):x(x),y(y) {}
};
cell start,finish;
queue<cell> c1;
int in(int x, int y)
{
if(x >= 1 && x <= n && y >=1 && y <= m)
return 1;
return 0;
}
void kindalee()
{
while(!c1.empty())
{
cell parent = c1.front();
for(int i = 0; i < 4; i++)
{
int x = parent.x + dx[i];
int y = parent.y + dy[i];
///verificam sa nu fie perete
if(in(x,y) == 1 && matrix[x][y] == -1)
{
matrix[x][y] = matrix[parent.x][parent.y] + 1;
c1.push(cell(x,y));
}
}
c1.pop();
}
}
bool bfs(int distance)
{
queue<cell> c2;
c2.push(start);
///nu uita sa resetezi vizitarile!!!
for(int i = 1; i <=n; i++)
for(int j = 1; j <=m; j++)
viz[i][j] = 0;
viz[start.x][start.y] = 1;
///ATENTIE! Trebuie verificat si startul (acesta NU ajunge in if-ul din for => nu se verifica
/// si valoarea matrixului corespunzatoare pozitiilor startului
if(matrix[start.x][start.y]>= distance)
while(!c2.empty())
{
cell parent = c2.front();
///am ajuns la finish => exista drum de distanta minim distance
if(parent.x == finish.x && parent.y == finish.y)
return true;
for(int i = 0; i < 4; i++)
{
int x = parent.x + dx[i];
int y = parent.y + dy[i];
///ca sa avem drum de distanta minim distance
/// matrix[x][y] >= distance si sa nu fie deja vizitat
if(in(x,y) == 1 && matrix[x][y] >= distance && !viz[x][y])
{
viz[x][y] = 1;
c2.push(cell(x,y));
}
}
c2.pop();
}
return false;
}
int maxdistance = -1;
void cautarebinara(int l, int r)
{
if(l <=r)
{
int m = l + (r - l)/2;
/// exista distanta minim m => incercam sa gasim una si mai mare => mergem in jumatatea din dreapta a
/// plajelor de valori
if(bfs(m))
{
maxdistance = m;
cautarebinara(m+1,r);
///ne salvam distanta
}
///altfel, mergem in jumatatea inferioara si cautam
else
cautarebinara(l,m-1);
}
}
int main()
{
///citim datele
fin>>n>>m;
for(int i= 1; i<=n; i++)
{
for(int j = 1; j <= m; j ++)
{
char c;
fin>>c;
if(c == 'D')
{
//adaugam dragonii in coada
c1.push(cell(i,j));
matrix[i][j] = 0;
}
else if(c == '*')
{
matrix[i][j] = -2;
}
else
{
//daca avem I sau O sau .
if (c == 'I')
start = cell(i,j);
if (c == 'O')
finish = cell(i,j);
matrix[i][j] = -1;
}
}
}
kindalee();
/* for(int i = 1 ; i <= n; i ++)
{
for(int j = 1; j <=m; j++)
{
cout<<" "<<matrix[i][j]<<" ";
}
cout<<"\n";
}*/
///facem o cautare binara
/// distanta minima = 0
/// distanta maxima = n*m
cautarebinara(0,n*m);
fout<<maxdistance;
return 0;
}