Pagini recente » Cod sursa (job #2769708) | Cod sursa (job #716034) | Cod sursa (job #212285) | Cod sursa (job #363778) | Cod sursa (job #690778)
Cod sursa(job #690778)
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAX 1050
using namespace std;
char matrice[MAX][MAX];
bool visit[MAX][MAX];
long long dist[MAX][MAX], b, sol = -1;
int r, c;
int depl_x[] = {-1, 0, 1, 0};
int depl_y[] = {0, 1, 0, -1};
struct point
{
int x, y;
bool operator==(point a)
{
return this->x == a.x && this->y == a.y;
}
} coada[MAX * MAX], start, stop;
void citire()
{
freopen("barbar.in", "r", stdin);
scanf("%d %d\n", &r, &c);
int i;
for(i = 0; i < r; i++)
gets(matrice[i]);
}
void prepare()
{
int i, j;
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
if(matrice[i][j] == 'D')
{
coada[++b].x = i;
coada[b].y = j;
dist[coada[b].x][coada[b].y] = 0;
visit[coada[b].x][coada[b].y] = true;
}
else
{
if(matrice[i][j] == 'I')
{
start.x = i;
start.y = j;
}
else if(matrice[i][j] == 'O')
{
stop.x = i;
stop.y = j;
}
dist[i][j] = MAX * MAX;
}
}
}
}
void genDist()
{
int a = 1, i;
while(a <= b)
{
for(i = 0; i < 4; i++)
{
if(coada[a].x + depl_x[i] >= 0 && coada[a].x + depl_x[i] < r &&
coada[a].y + depl_y[i] >= 0 && coada[a].y + depl_y[i] < c &&
matrice[coada[a].x + depl_x[i]][coada[a].y + depl_y[i]] != '*')
{
if(!visit[coada[a].x + depl_x[i]][coada[a].y + depl_y[i]])
{
coada[++b].x = coada[a].x + depl_x[i];
coada[b].y = coada[a].y + depl_y[i];
dist[coada[b].x][coada[b].y] = dist[coada[a].x][coada[a].y] + 1;
visit[coada[a].x + depl_x[i]][coada[a].y + depl_y[i]] = true;
}
else if(dist[coada[a].x + depl_x[i]][coada[a].y + depl_y[i]] > dist[coada[a].x][coada[a].y] + 1)
{
dist[coada[a].x + depl_x[i]][coada[a].y + depl_y[i]] = dist[coada[a].x][coada[a].y] + 1;
}
}
}
a++;
}
}
bool lee(long long minim)
{
long long a = 1, i;
b = 1;
while(a <= b)
{
for(i = 0; i < 4; i++)
{
if(coada[a].x + depl_x[i] >= 0 && coada[a].x + depl_x[i] < r &&
coada[a].y + depl_y[i] >= 0 && coada[a].y + depl_y[i] < c &&
!visit[coada[a].x + depl_x[i]][coada[a].y + depl_y[i]] &&
matrice[coada[a].x + depl_x[i]][coada[a].y + depl_y[i]] != '*' &&
dist[coada[a].x + depl_x[i]][coada[a].y + depl_y[i]] >= minim)
{
coada[++b].x = coada[a].x + depl_x[i];
coada[b].y = coada[a].y + depl_y[i];
visit[coada[b].x][coada[b].y] = true;
if(coada[b] == stop)
return true;
}
}
a++;
}
return false;
}
void caut()
{
long long begin = 0, end = dist[start.x][start.y], mid = (begin + end) >> 1;
while(begin <= end)
{
memset(visit, 0, MAX * MAX * sizeof(bool));
memset(coada, 0, MAX * MAX * sizeof(point));
if(lee(mid))
{
sol = mid;
begin = mid + 1;
}
else
{
end = mid - 1;
}
mid = (begin + end) >> 1;
}
}
void afisare()
{
freopen("barbar.out", "w", stdout);
printf("%lld", sol);
fclose(stdout);
}
int main()
{
citire();
prepare();
genDist();
caut();
afisare();
return 0;
}