Pagini recente » sin | simple_oni_sim | Cod sursa (job #1868043) | Cod sursa (job #3260552) | Cod sursa (job #3343005)
#include <fstream>
#include <queue>
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
struct cell
{
int dist;
bool Dvisited = false;
bool Pvisited = false;
bool isWall = false;
bool isExit = false;
};
int n,m;
cell prison[1005][1005];
queue<pair<int, int>> q;
int stPointi, stPointj;
void read()
{
fin >> n >> m;
for(int i = 0; i < n; ++i){
for(int j = 0; j < m; ++j){
char c;
fin >> c;
if(c == 'I'){
stPointi = i;
stPointj = j;
}
else if(c == 'D'){
prison[i][j].Dvisited = true;
prison[i][j].dist = 0;
q.push(make_pair(i, j));
}
else if(c == '*'){
prison[i][j].isWall = true;
}
else if(c == 'O'){
prison[i][j].isExit = true;
}
}
}
}
void bfs()
{
while(!q.empty()){
int i = q.front().first;
int j = q.front().second;
q.pop();
if(!prison[i + 1][j].Dvisited && i + 1 < n){
prison[i + 1][j].Dvisited = true;
prison[i + 1][j].dist = prison[i][j].dist + 1;
q.push(make_pair(i + 1, j));
}
if(!prison[i - 1][j].Dvisited && i > 0){
prison[i - 1][j].Dvisited = true;
prison[i - 1][j].dist = prison[i][j].dist + 1;
q.push(make_pair(i - 1, j));
}
if(!prison[i][j + 1].Dvisited && j + 1 < m){
prison[i][j + 1].Dvisited = true;
prison[i][j + 1].dist = prison[i][j].dist + 1;
q.push(make_pair(i, j + 1));
}
if(!prison[i][j - 1].Dvisited && j > 0){
prison[i][j - 1].Dvisited = true;
prison[i][j - 1].dist = prison[i][j].dist + 1;
q.push(make_pair(i, j - 1));
}
}
}
bool path(int x, int y, int d)
{
for(int i = 0; i < n; ++i){
for(int j = 0; j < m; ++j){
if(i == x && j == y){
prison[i][j].Pvisited = true;
}
else{
prison[i][j].Pvisited = false;
}
}
}
while(!q.empty()){
q.pop();
}
q.push(make_pair(x, y));
while(!q.empty()){
int i = q.front().first;
int j = q.front().second;
if(prison[i][j].isExit){
return true;
}
q.pop();
if(!prison[i + 1][j].Pvisited && i + 1 < n && !prison[i + 1][j].isWall && prison[i + 1][j].dist >= d){
prison[i + 1][j].Pvisited = true;
q.push(make_pair(i + 1, j));
}
if(!prison[i - 1][j].Pvisited && i > 0 && !prison[i - 1][j].isWall && prison[i - 1][j].dist >= d){
prison[i - 1][j].Pvisited = true;
q.push(make_pair(i - 1, j));
}
if(!prison[i][j + 1].Pvisited && j + 1 < m && !prison[i][j + 1].isWall && prison[i][j + 1].dist >= d){
prison[i][j + 1].Pvisited = true;
q.push(make_pair(i, j + 1));
}
if(!prison[i][j - 1].Pvisited && j > 0 && !prison[i][j - 1].isWall && prison[i][j - 1].dist >= d){
prison[i][j - 1].Pvisited = true;
q.push(make_pair(i, j - 1));
}
}
return false;
}
void binarySearch()
{
int l = 0, r = 8;
int ans;
while(l <= r){
int m = (l + r) / 2;
if(path(stPointi, stPointj, m)){
l = m + 1;
ans = m;
}
else{
r = m - 1;
}
}
if(path(stPointi, stPointj, ans)){
fout << ans;
}
else{
fout << -1;
}
}
int main()
{
read();
bfs();
binarySearch();
return 0;
}