Pagini recente » Cod sursa (job #1007133) | Cod sursa (job #1403589) | Cod sursa (job #2037826) | Cod sursa (job #504536) | Cod sursa (job #2298199)
#include <fstream>
#include <vector>
//#include <queue>
#define input "barbar.in"
#define output "barbar.out"
#define MATRIX_SIZE 1005
using namespace std;
ifstream in(input);
ofstream out(output);
//-----Queue declares Area-----
struct inf
{
int x, y;
};
struct nod
{
inf info;
nod *next;
};
typedef nod* queue;
void Push_Back(queue &coada, queue &tail, inf informatii)
{
queue aux = new nod;
aux->info = informatii;
if (!coada) coada = aux, tail = coada;
else
{
tail->next = aux;
tail = tail->next;
}
}
void Pop_Front(queue &coada, queue &tail)
{
if (!coada && !tail) return;
if (coada == tail)
{
queue aux = coada;
coada = tail = NULL;
delete aux;
return;
}
// Daca niciunul din cazurile exceptate nu se regaseste, vom elimina
queue aux = coada;
coada = coada->next;
delete aux;
}
bool Empty(queue coada, queue tail)
{
if (coada == tail && coada == NULL) return true;
return false;
}
inf Get_Front(queue coada, queue tail)
{
return coada->info;
}
//-----End Queue declares Area-----
int dx[] = { -1, 1, 0, 0 };
int dy[] = { 0, 0, -1, 1 };
queue coada, tail;
int N, M, map[MATRIX_SIZE][MATRIX_SIZE], dragon_distance[MATRIX_SIZE][MATRIX_SIZE];
inf start_point, stop_point;
inline bool OK_Dragon(int x, int y)
{
if (x < 1 || x > N || y < 1 || y > M)
return false;
if (dragon_distance[x][y])
return false;
return true;
}
inline bool OK(int x, int y)
{
if (x < 1 || x > N || y < 1 || y > M)
return false;
if (map[x][y] > 0 || map[x][y] == -1)
return false;
return true;
}
void Read_Data()
{
char c;
in >> N >> M;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= M; j++)
{
in >> c;
if (c == 'I') start_point = { i, j };
else if (c == 'O') stop_point = { i, j };
else if (c == 'D') Push_Back(coada, tail, { i, j }), dragon_distance[i][j] = 1;
else if (c == '*') map[i][j] = -1, dragon_distance[i][j] = -1;;
}
}
void Lee_Dragon()
{
while (!Empty(coada, tail))
{
inf date = Get_Front(coada, tail);
Pop_Front(coada, tail);
for (int d = 0; d < 4; d++)
{
int x_new = date.x + dx[d];
int y_new = date.y + dy[d];
if (OK_Dragon(x_new, y_new))
{
dragon_distance[x_new][y_new] = dragon_distance[date.x][date.y] + 1;
Push_Back(coada, tail, { x_new, y_new });
}
}
}
}
void Print_Sol_Dragon()
{
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= M; j++)
out << dragon_distance[i][j] << " ";
out << "\n";
}
out << "\n";
}
void Print_Sol()
{
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= M; j++)
out << map[i][j] << " ";
out << "\n";
}
out << "\n";
}
void Decrease_by_one()
{
for (int i = 1; i <= N; i++)
for (int j = 1; j <= M; j++)
dragon_distance[i][j]--;
}
void Redo()
{
for (int i = 1; i <= N; i++)
for (int j = 1; j <= M; j++)
if (map[i][j] != -1) map[i][j] = 0;
}
inline bool Lee(int val)
{
if (dragon_distance[start_point.x][start_point.y] < val) return false;
map[start_point.x][start_point.y] = 1;
Push_Back(coada, tail, start_point);
while (!Empty(coada, tail))
{
inf date = Get_Front(coada, tail);
Pop_Front(coada, tail);
for (int d = 0; d < 4; d++)
{
int x_new = date.x + dx[d];
int y_new = date.y + dy[d];
if (OK(x_new, y_new) && dragon_distance[x_new][y_new] >= val)
{
map[x_new][y_new] = map[date.x][date.y] + 1;
Push_Back(coada, tail, { x_new, y_new });
}
}
}
if (map[stop_point.x][stop_point.y] > 0) return true;
return false;
}
void Binary_Search()
{
int optim = -1;
int st = 0, dr = 1000;
while (st <= dr)
{
int mid = (st + dr) / 2;
bool valid = Lee(mid);
//out << mid << " " << valid << "\n";
//Print_Sol();
Redo();
if (valid) optim = mid, st = mid + 1;
else dr = mid - 1;
}
out << optim << "\n";
}
void Control_Function()
{
Read_Data();
// Dragons files
Lee_Dragon();
Decrease_by_one();
//Print_Sol_Dragon();
// Cautarea solutiei
Binary_Search();
}
int main()
{
Control_Function();
return 0;
}