Pagini recente » Cod sursa (job #688266) | Cod sursa (job #2430904) | Cod sursa (job #554301) | Cod sursa (job #2966195) | Cod sursa (job #514225)
Cod sursa(job #514225)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef enum { Dragon, Free, Wall } CellType;
typedef struct Cell{
CellType type;
int cost;
} Cell;
int dx[4] = { 0, 0, 1,-1 };
int dy[4] = {-1, 1, 0, 0 };
typedef struct Pos {
int X, Y;
Pos *next;
} Pos;
Pos Start, End;
Pos** queue;
int lq;
Cell** grid;
bool** inQueue;
int N, M;
void allocGrid(int &N, int &M) {
char cell;
Pos *element;
scanf("%d %d\n", &N, &M);
queue = (Pos**) malloc(N*M*sizeof(Pos*));
grid = (Cell**) malloc(N*sizeof(Cell*));
inQueue = (bool**) malloc(N*sizeof(bool*));
for ( int i = 0; i < N; i++ ) {
grid[i] = (Cell*) malloc(M*sizeof(Cell));
inQueue[i] = (bool*) malloc(M*sizeof(bool));
for ( int j = 0; j < M; j++ ) {
scanf("%c", &cell);
switch(cell) {
case '.': grid[i][j].type = Free; break;
case 'D': grid[i][j].type = Dragon;
element = (Pos*) malloc(sizeof(Pos));
element->X = i; element->Y = j;
inQueue[i][j] = true;
queue[lq++] = element;
break;
case '*': grid[i][j].type = Wall; break;
case 'I': grid[i][j].type = Free;
Start.X = i; Start.Y = j;
break;
case 'O': grid[i][j].type = Free;
End.X = i; End.Y = j;
break;
default: break;
}
}
scanf("%c\n", &cell);
}
}
Cell* cellAt(Pos *pos) {
return &grid[pos->X][pos->Y];
}
void clearQueue() {
for(int i = 0; i < lq; i++) {
inQueue[queue[i]->X][queue[i]->Y] = false;
free(queue[i]);
}
lq = 0;
}
int minDistToCheck;
bool valid1(Pos *pos) {
return pos->X >= 0 && pos->X < N && pos->Y >= 0 && pos->Y < M &&
!inQueue[pos->X][pos->Y] && cellAt(pos)->type == Free;
}
bool valid2(Pos *pos) {
return pos->X >= 0 && pos->X < N && pos->Y >= 0 && pos->Y < M &&
!inQueue[pos->X][pos->Y] && cellAt(pos)->type != Wall &&
cellAt(pos)->cost >= minDistToCheck;
}
void enqueue1(Pos *old_pos, Pos *pos) {
cellAt(pos)->cost = cellAt(old_pos)->cost + 1;
queue[lq++] = pos;
inQueue[pos->X][pos->Y] = true;
}
void enqueue2(Pos *old_pos, Pos *pos) {
queue[lq++] = pos;
inQueue[pos->X][pos->Y] = true;
}
void eachValidNeibourgh(Pos *pos, bool(*valid)(Pos *pos), void(*block)(Pos *old_pos, Pos *pos )) {
for (int i = 0; i < 4; i++) {
Pos *new_pos = (Pos*) malloc(sizeof(Pos));
new_pos->X = pos->X + dx[i];
new_pos->Y = pos->Y + dy[i];
if ( valid(new_pos) ) {
block(pos, new_pos);
} else {
free(new_pos);
}
}
}
bool isEqual(Pos *A, Pos *B) {
return (A->X == B->X) && (A->Y == B->Y);
}
Pos* copy(Pos A) {
Pos *ret = (Pos *) malloc(sizeof(Pos));
memcpy(ret, &A, sizeof(Pos));
return ret;
}
void printQueue() {
for ( int i = 0; i < lq; i++ ) {
printf("[%d,%d | %d]\n", queue[i]->X, queue[i]->Y, cellAt(queue[i])->cost);
}
printf("\n");
}
bool canTraverse(int dist) {
clearQueue();
if (cellAt(&Start)->cost >= dist)
enqueue2(NULL, copy(Start));
minDistToCheck = dist;
for (int i = 0; i < lq; i++) {
if (isEqual(queue[i], &End)) return true;
eachValidNeibourgh(queue[i], valid2, enqueue2);
}
return false;
}
int main() {
freopen("barbar.in", "r", stdin);
freopen("barbar.out", "w", stdout);
allocGrid(N, M);
for (int i = 0; i < lq; i++) {
eachValidNeibourgh(queue[i], valid1, enqueue1);
}
/*for (int i = 0; i < N; i++, printf("\n"))
for (int j = 0; j < M; j++) {
printf("%d ", grid[i][j].cost);
} */
int step, max_dist;
for (step = 1; step < (N+M); step <<= 1 );
for (max_dist = 0; step; step >>= 1) {
if (canTraverse(max_dist + step)) max_dist += step;
}
if (!canTraverse(0)) printf("-1\n");
else printf("%d\n", max_dist);
}