Pagini recente » Cod sursa (job #3282451) | Cod sursa (job #1288644) | Cod sursa (job #275317) | Cod sursa (job #919959) | Cod sursa (job #1703343)
#include <fstream>
#include <string.h>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
const int NMAX = 1000000;
int mat[1005][1005], n, m, viz[1002][1002];
char s[1002];
int dx[] = {-1, 0, 0, 1};
int dy[] = {0, 1, -1, 0};
struct point{
int x, y;
};
point start, fin;
vector<point> drag;
void wipe(){
int i, j;
for(i = 1; i <= n; ++i){
for(j = 1; j <= m; ++j){
viz[i][j] = 0;
}
}
}
bool path(int val){
queue<point> q;
int k;
bool ok1 = 0, ok2 = 0;
point curr, next;
q.push({start.x, start.y});
wipe();
viz[start.x][start.y] = 1;
if(mat[start.x][start.y] >= val + 1){
if(mat[start.x][start.y] == val + 1) ok1 = 1;
while(!q.empty()){
curr = q.front();
q.pop();
for(k = 0; k < 4; ++k){
next.x = curr.x + dx[k];
next.y = curr.y + dy[k];
if(mat[next.x][next.y] > val + 1 && viz[next.x][next.y] == 0){
q.push(next);
viz[next.x][next.y] = 1;
if(next.x == fin.x && next.y == fin.y) ok2 = 1;
}
else if(mat[next.x][next.y] == val + 1 && viz[next.x][next.y] == 0){
q.push(next);
ok1 = 1;
viz[next.x][next.y] = 1;
if(next.x == fin.x && next.y == fin.y) ok2 = 1;
}
}
}
if(ok1 == 1 && ok2 == 1){
return 1;
}
else{
return 0;
}
}
return 0;
}
int bin_search(){
int med, lf = 0, rg = NMAX, rez = -1;
while(lf <= rg){
med = (lf + rg) / 2;
if(path(med)){
lf = med + 1;
rez = med;
}
else{
rg = med - 1;
}
}
return rez;
}
void bordare(){
int i;
for(i = 0; i <= m + 1; ++i){
mat[0][i] = -1;
mat[n+1][i] = -1;
}
for(i = 0; i <= n + 1; ++i){
mat[i][0] = -1;
mat[i][m+1] = -1;
}
}
void lee_drag(){
queue<point> q;
int i, k;
point curr, next;
for(i = 0; i < (int)drag.size(); ++i) q.push(drag[i]);
while(!q.empty()){
curr = q.front();
q.pop();
for(k = 0; k < 4; ++k){
next.x = curr.x + dx[k];
next.y = curr.y + dy[k];
if(mat[next.x][next.y] >= 0){
if(mat[curr.x][curr.y] > 1 && mat[next.x][next.y] == 0){
mat[next.x][next.y] = mat[curr.x][curr.y] + 1;
q.push(next);
}
else if(mat[curr.x][curr.y] > 1 && mat[next.x][next.y] != 0){
if(mat[curr.x][curr.y] + 1 < mat[next.x][next.y]) mat[next.x][next.y] = mat[curr.x][curr.y] + 1, q.push(next);
}
else{
mat[next.x][next.y] = 2;
q.push(next);
}
}
}
}
}
int main()
{
int i, j, len, sol;
freopen("barbar.in", "r", stdin);
freopen("barbar.out", "w", stdout);
scanf("%d%d\n", &n, &m);
for(i = 1; i <= m; ++i){
gets(s);
len = strlen(s);
for(j = 0; j < len; ++j){
if(s[j] == '.') mat[i][j+1] = 0;
if(s[j] == '*') mat[i][j+1] = -1;
if(s[j] == 'I') start = {i, j+1};
if(s[j] == 'O') fin = {i, j+1};
if(s[j] == 'D'){
mat[i][j+1] = 1;
drag.push_back({i, j+1});
}
}
}
bordare();
lee_drag();
if(start.x == fin.x && start.y == fin.y){
printf("%d", mat[start.x][start.y] - 1);
}
else{
sol = bin_search();
printf("%d", sol);
}
return 0;
}