Pagini recente » Cod sursa (job #324862) | Cod sursa (job #727131) | Cod sursa (job #995947) | Cod sursa (job #1977276) | Cod sursa (job #1400653)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#define NMAX 1005
using namespace std;
bool wall[NMAX][NMAX];
bool visited[NMAX][NMAX];
char dragon_map[NMAX][NMAX];
int distance_map[NMAX][NMAX];
int move_x[4] = { 1, 0, -1, 0 };
int move_y[4] = { 0, 1, 0, -1 };
struct point {
point(int _x, int _y):x(_x),y(_y),distance(0){};
point():x(0),y(0),distance(0){};
void set_coords(short _x, short _y) { this->x = _x; this->y = _y; }
void print() { printf("Point: x: %d, y: %d\n", this->x, this->y); }
int x, y;
int distance;
};
int N, M;
point start_point, end_point;
void print_distance_map() {
for (int i = 0; i <= N + 1; i++) {
for (int j = 0; j <= M + 1; j++) {
cout << distance_map[i][j];
}
cout << endl;
}
}
void print_wall() {
for (int i = 0; i <= N + 1; i++) {
for (int j = 0; j <= M + 1; j++) {
if (wall[i][j]) { cout << "#"; }
else { cout << "."; }
}
cout << endl;
}
}
void print_visited() {
for (int i = 0; i <= N + 1; i++) {
for (int j = 0; j <= M + 1; j++) {
if (visited[i][j]) { cout << "#"; }
else { cout << "."; }
}
cout << endl;
}
}
void reset_visited() {
for (int i = 0; i <= N + 1; i++) {
for (int j = 0; j <= M + 1; j++) {
visited[i][j] = false;
}
}
}
struct compare_point_distance {
bool operator() (const point& lhs, const point&rhs) const {
return lhs.distance < rhs.distance;
}
};
int main() {
if (freopen("barbar.in", "r", stdin) == NULL ||
freopen("barbar.out", "w", stdout) == NULL) return 1;
cin >> N >> M;
queue<point> q;
for (int i = 0; i <= N + 1; i++) wall[i][0] = wall[i][M + 1] = true;
for (int j = 0; j <= M + 1; j++) wall[0][j] = wall[N + 1][j] = true;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
char c;
cin >> c;
dragon_map[i][j] = c;
if (c == '*') { wall[i][j] = true; }
if (c == 'I') { start_point.set_coords(i, j); }
if (c == 'O') { end_point.set_coords(i, j); }
if (c == 'D') {
point dragon_point(i, j);
visited[i][j] = true;
q.push(dragon_point);
};
}
}
while(!q.empty()) {
point current_point = q.front();
q.pop();
//current_point.print();
distance_map[current_point.x][current_point.y] = current_point.distance;
for (int i = 0; i < 4; i++) {
point new_point(current_point.x + move_x[i], current_point.y + move_y[i]);
new_point.distance = current_point.distance + 1;
if (!wall[new_point.x][new_point.y] && !visited[new_point.x][new_point.y]) {
visited[new_point.x][new_point.y] = true;
q.push(new_point);
distance_map[new_point.x][new_point.y] = new_point.distance;
}
}
}
reset_visited();
priority_queue<point, vector<point>, compare_point_distance> pq;
start_point.distance = distance_map[start_point.x][start_point.y];
pq.push(start_point);
while(!pq.empty()) {
point current_point = pq.top();
pq.pop();
if (current_point.x == end_point.x && current_point.y == end_point.y) {
printf("%d\n", current_point.distance);
break;
}
for (int i = 0; i < 4; i++) {
point new_point(current_point.x + move_x[i], current_point.y + move_y[i]);
new_point.distance = min(current_point.distance, distance_map[new_point.x][new_point.y]);
if (!wall[new_point.x][new_point.y] && !visited[new_point.x][new_point.y]) {
visited[new_point.x][new_point.y] = true;
pq.push(new_point);
}
}
}
return 0;
}