Cod sursa(job #2839931)

Utilizator StefanL2005Stefan Leustean StefanL2005 Data 26 ianuarie 2022 19:13:21
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.75 kb
#include <iostream>
#include <vector>
#include <queue>
#include <fstream>
using namespace std;
ifstream in ("barbar.in");
ofstream out ("barbar.out");

bool drum(int n, int R, int C, pair<int, int> paftenie, pair<int, int> Final, vector< vector<int> > dragon)
{
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};

    vector< vector<int> > Hero(R, vector<int> (C, R * C + 2));
    Hero[paftenie.first][paftenie.second] = 0;

    queue< pair<int, int> > Q;
    Q.push(paftenie);

    if (dragon[paftenie.first][paftenie.second] >= n)
        while (not Q.empty())
        {
            pair<int, int> node = Q.front();
            Q.pop();

                for (int i = 0; i < 4; i++)
            {
                pair<int, int> vecin = make_pair(node.first + dx[i], node.second + dy[i]);

                if (vecin.first < 0 || vecin.second < 0 || vecin.first >= R || vecin.second >= C)
                    continue;

                if (dragon[vecin.first][vecin.second] < n || dragon[vecin.first][vecin.second] ==  R * C + 2)
                    continue;

                if (Hero[vecin.first][vecin.second] > Hero[node.first][node.second] + 1)
                {
                    Hero[vecin.first][vecin.second] = Hero[node.first][node.second] + 1;
                    Q.push(vecin);
                }
            }
        }
    if (Hero[Final.first][Final.second] != R * C + 2)
        return true;
    else
        return false;
}

int main()
{
    int R, C, nr = 0, Max = 0;
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    in>> R >> C;

    vector<string> traseu(R);
    pair<int, int> paftenie, Final;
    vector< pair<int, int> > D;

    for (int i = 0; i < R; i++)
    {
        in>> traseu[i];

        for (int j = 0; j < C; j++)
        {
            if (traseu[i][j] == 'I')
                paftenie = make_pair(i, j);
            if (traseu[i][j] == 'D')
            {
                D.push_back(make_pair(i, j));
                nr++;
            }
            if (traseu[i][j] == 'O')
                Final = make_pair(i, j);
        }
    }

    vector< vector<int> > dragon(R, vector<int> (C, R * C + 2));
    queue< pair<int, int> > Q;

    for (int i = 0; i < nr; i++)
    {
        dragon[D[i].first][D[i].second] = 0;
        Q.push(D[i]);
    }

    while (not Q.empty())
    {
        pair<int, int> node = Q.front();
        Q.pop();

        for (int i = 0; i < 4; i++)
        {
            pair<int, int> vecin = make_pair(node.first + dx[i], node.second + dy[i]);

            if (vecin.first < 0 || vecin.second < 0 || vecin.first >= R || vecin.second >= C)
                continue;

            if (traseu[vecin.first][vecin.second] == '*')
                continue;

            if (dragon[vecin.first][vecin.second] > dragon[node.first][node.second] + 1)
            {
                dragon[vecin.first][vecin.second] = dragon[node.first][node.second] + 1;
                Q.push(vecin);
                if (dragon[vecin.first][vecin.second] > Max)
                    Max = dragon[vecin.first][vecin.second];
            }
        }
    }
    int c1 = 1, c2 = Max;
    if (nr == 0)
        out<< 0;
    else
        if (not drum(0, R, C, paftenie, Final, dragon))
            out<< -1;
        else
        {
            while (c2 - c1 > 1)
            {
                int m = (c1 + c2) / 2;
                if (drum(m, R, C, paftenie, Final, dragon))
                    c1 = m;
                else
                    c2 = m;
            }
            if (drum(c2, R, C, paftenie, Final, dragon))
                out<< c2;
            else
                out<< c1;
        }

    in.close();
    out.close();
    return 0;
}