Cod sursa(job #2840879)

Utilizator raulandreipopRaul-Andrei Pop raulandreipop Data 28 ianuarie 2022 21:38:20
Problema Barbar Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.56 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#define f first
#define s second

using namespace std;

ifstream in ("barbar.in");
ofstream out ("barbar.out");

struct coord {
    int x, y;
    int dist;
};

char maze[1010][1010];
int dd[1001][1001];
pair<int, int> dir[] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
coord I, O; int n, m;

bool dungeon (int p)
{
    queue<coord> q;
    vector<vector<bool>> viz;
    viz.resize(n + 1);
    for (int i = 1; i <= n; i++){
        viz[i].resize(m + 1);
    }
    q.push(I);
    while (!q.empty())
    {
        coord crt = q.front();
     //   cout << crt.dist << '\n';
        q.pop();
        for (auto dr : dir)
        {
            int x = crt.x + dr.f, y = crt.y + dr.s;
            if (x < 1 || x > n || y < 1 || y > m) continue;
            if (!viz[x][y] && maze[x][y] == '.' && dd[x][y] >= p)
            {
                
                viz[x][y] = 1;
                q.push({x, y, 0});
            }
            else if (maze[x][y] == 'O') return 1;
            
        }
    }
    return 0;
}

int main ()
{
    in >> n >> m;
    queue<coord> d;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++){
            in >> maze[i][j];
            dd[i][j] = 1e9;
            if (maze[i][j] == 'I') I = {i, j, 0};
            else if (maze[i][j] == 'D') {
                d.push({i, j, 0});
                dd[i][j] = 0;
            }
            else if (maze[i][j] == 'O') O = {i, j, 0};
        }
    }
    for (int i = 1; i <= n; i++)
    {
        maze[i][m+1] = '*';
        maze[i][0] = '*';
    }
    for (int i = 1; i <= n; i++)
    {
        maze[n+1][i] = '*';
        maze[0][i] = '*';
    }
   
    while (!d.empty())
    {
        coord crt = d.front();
        
        d.pop();
        int i = crt.x, j = crt.y;
        if (crt.dist > dd[i][j]) continue;
        for (auto dr : dir)
        {
            int x = i + dr.f, y = j + dr.s;
            if (x > n || y > m || x < 1 || y < 1) continue;
            if (dd[x][y] > crt.dist + 1 && maze[x][y] != '*')
            {
                dd[x][y] = crt.dist + 1;
                d.push({x, y, dd[x][y]});
            }
        }
    }
    int l = 0, h = n + m;
    int ans;
    while (l < h)
    {
        int mid = (l + h) / 2;
        bool done = dungeon(mid);
        if (done) {
            l = mid + 1; ans = mid;
        }
        else {
            h = mid; 
        }
    }
    if (ans == 0) out << -1;
    else 
        out << ans;
}