Cod sursa(job #2444519)

Utilizator PatrickCplusplusPatrick Kristian Ondreovici PatrickCplusplus Data 31 iulie 2019 17:33:57
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.09 kb
#include <fstream>
#include <queue>
#define INF 1012036
using namespace std;
ifstream cin("barbar.in");
ofstream cout("barbar.out");
int n, m, dp[1006][1006][2], dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1}, x, y, xx, yy;
char matrix[1006][1006];
queue <pair <int, int> > coada;
void Read()
{
    cin >> n >> m;
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= m; ++j)
        {
            cin >> matrix[i][j];
            dp[i][j][0] = INF;
            dp[i][j][1] = -INF;
            if (matrix[i][j] == 'D')
            {
                dp[i][j][0] = 0;
                coada.push({i, j});
            }
            if (matrix[i][j] == 'I')
            {
                x = i;
                y = j;
            }
            if (matrix[i][j] == 'O')
            {
                xx = i;
                yy = j;
            }
        }
    }
}
bool Valid(int i, int j)
{
    return i >= 1 && i <= n && j >= 1 && j <= m && matrix[i][j] != '*';
}

bool bfs(int mid)
{
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= m; ++j)
        {
            dp[i][j][1] = INF;
        }
    }
    if (dp[x][y][0] < mid) return false;
    dp[x][y][1] = 0;
    coada.push({x, y});
    while (!coada.empty())
    {
        int i = coada.front().first;
        int j = coada.front().second;
        coada.pop();
        for (int k = 0; k < 4; ++k)
        {
            int ii = i + dx[k];
            int jj = j + dy[k];
            if (Valid(ii, jj) && dp[ii][jj][1] == INF && dp[ii][jj][0] >= mid)
            {
                dp[ii][jj][1] = 1 + dp[i][j][1];
                coada.push({ii, jj});
            }
        }
    }
    if (dp[xx][yy][1] == INF) return false;
    return true;
}

void Solve()
{
    while (!coada.empty())
    {
        int i = coada.front().first;
        int j = coada.front().second;
        coada.pop();
        for (int k = 0; k < 4; ++k)
        {
            int ii = i + dx[k];
            int jj = j + dy[k];
            if (Valid(ii, jj) && dp[ii][jj][0] > dp[i][j][0] + 1)
            {
                dp[ii][jj][0] = 1 + dp[i][j][0];
                coada.push({ii, jj});
            }
        }
    }
    /*
    dp[x][y][1] = dp[x][y][0];
    coada.push({x, y});
    while (!coada.empty())
    {
        int i = coada.front().first;
        int j = coada.front().second;
        coada.pop();
        for (int k = 0; k < 4; ++k)
        {
            int ii = i + dx[k];
            int jj = j + dy[k];
            if (Valid(ii, jj) && dp[ii][jj][1] < min(dp[i][j][1], dp[ii][jj][0]))
            {
                dp[ii][jj][1] = min(dp[i][j][1], dp[ii][jj][0]);
                coada.push({ii, jj});
            }
        }
    }
    */
    int st = 1, dr = n * m, sol = -1;
    while (st <= dr)
    {
        int mid = (st + dr) / 2;
        if (bfs(mid))
        {
            sol = mid;
            st = mid + 1;
        }
        else
        {
            dr = mid - 1;
        }
    }
    cout << sol;
}
int main()
{
    Read();
    Solve();
	return 0;
}