Pagini recente » Cod sursa (job #277310) | Cod sursa (job #599893) | Cod sursa (job #809594) | Cod sursa (job #2440457) | Cod sursa (job #2671980)
#include <iostream>
#include <fstream>
#include <queue>
using namespace std;
int R, C;
#define max_n 1002
int M[max_n][max_n];
struct Location{
int x;
int y;
};
queue<Location> q;
Location start, finish;
int biggestDistVal;
void BFS( ){
Location current;
while(!q.empty()){
current = q.front();
// right
if ( current.x+1 < C ){
if ( M[current.x+1][current.y] == -1 ) {
M[current.x+1][current.y] = M[current.x][current.y] + 1;
if ( biggestDistVal < M[current.x+1][current.y] ) { biggestDistVal = M[current.x+1][current.y]; }
q.push({current.x+1, current.y});
}
}
// left
if ( current.x-1 >= 0 ){
if ( M[current.x-1][current.y] == -1 ) {
M[current.x-1][current.y] = M[current.x][current.y] + 1;
if ( biggestDistVal < M[current.x-1][current.y] ) { biggestDistVal = M[current.x-1][current.y]; }
q.push({current.x-1, current.y});
}
}
// down
if ( current.y+1 < R ){
if ( M[current.x][current.y+1] == -1 ) {
M[current.x][current.y+1] = M[current.x][current.y] + 1;
if ( biggestDistVal < M[current.x][current.y+1] ) { biggestDistVal = M[current.x][current.y+1]; }
q.push({current.x, current.y+1});
}
}
// up
if ( current.y-1 >= 0 ){
if ( M[current.x][current.y-1] == -1 ) {
M[current.x][current.y-1] = M[current.x][current.y] + 1;
if ( biggestDistVal < M[current.x][current.y-1] ) { biggestDistVal = M[current.x][current.y-1]; }
q.push({current.x, current.y-1});
}
}
q.pop();
}
}
// up down right left
int dx[4] = { 0, 0, 1, -1 };
int dy[4] = { -1, 1, 0, 0 };
int visited[max_n][max_n];
int currentlyVisited = 1;
struct QueueElem{
Location l;
int dist;
};
bool look( int minimal ){
queue<QueueElem> qu;
QueueElem c;
qu.push({start.x, start.y, M[start.x][start.y]});
Location next;
while(!qu.empty()){
c = qu.front();
visited[c.l.x][c.l.y] = currentlyVisited;
for ( int i = 0; i < 4; i++ ){
next.x = c.l.x + dx[i];
next.y = c.l.y + dy[i];
if ( next.x >= 0 && next.x < C && next.y >= 0 && next.y < R ){
//cout << "next " << next.x << ' ' << next.y << endl;
//if ( M[next.x][next.y] != -2 ) {
if ( visited[next.x][next.y] < currentlyVisited && M[next.x][next.y] >= minimal ){
//cout << "current " << c.l.x << ' ' << c.l.y << ' ' << next.x << ' ' << next.y << endl;
if ( next.x == finish.x && next.y == finish.y ){
//cout << "Found the finish";
currentlyVisited++;
return true;
}
qu.push({next, min(M[next.x][next.y], c.dist)});
visited[next.x][next.y] = currentlyVisited;
}
// }
}
}
qu.pop();
}
currentlyVisited++;
return false;
}
/*
10 10
..........
.I....D...
..........
..D...D...
.*........
D*........
*...D.....
..****....
...O......
..........
. celula libera
* perete
D dragon
I punctul de plecare al lui Paftenie
O iesirea din temnita
*/
int main() {
ifstream fin("barbar.in");
ofstream fout("barbar.out");
fin >> R >> C;
char temp;
Location dragon;
for ( int y = 0; y < R; y++ ){
for ( int x = 0; x < C; x++ ){
fin >> temp;
switch(temp){
case 'O':
finish.x = x;
finish.y = y;
M[x][y] = -1;
break;
case 'I':
start.x = x;
start.y = y;
M[x][y] = -1;
break;
case '.':
M[x][y] = -1;
break;
case 'D':{
M[x][y] = 0;
dragon.x = x;
dragon.y = y;
q.push(dragon);
break;
}
case '*':
M[x][y] = -2;
break;
}
}
}
BFS();
/*
for ( int y = 0; y < R; y++ ){
for ( int x = 0; x < C; x++ ){
cout << M[x][y] << ' ';
}
cout << endl;
}*/
// in cazul in care I = O
if ( finish.x == start.x && finish.y == start.y ){
fout << M[start.x][start.y];
return 0;
}
int r = -1;
/*
for ( int i = 0; i < biggestDistVal; i++ ){
if ( look( i ) ) {
r = i;
} else {
break;
}
}*/
int low = 0;
int high = biggestDistVal;
int mid = (low+high)/2;
while ( high != low && low != mid ){
if ( look(mid) ){ // can get higher
r = mid;
low = mid;
mid = (low+high)/2;
} else { // can get lower
high = mid;
mid = (low+high)/2;
}
//cout << low << ' ' << mid << ' ' << high << endl;
}
for ( int i = 0; i < 3; i++ ){
if ( look(mid-2+i) ){
if ( r < mid-2+i )
r = mid-2+i;
} else {
break;
}
}
//cout << finish.x << ' ' << finish.y;
fout << r;
fout.close();
fin.close();
return 0;
}